CTAOS v6
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,635 @@
|
|||||||
|
================================================================
|
||||||
|
IBM PC KEYBOARD INFORMATION FOR SOFTWARE DEVELOPERS
|
||||||
|
================================================================
|
||||||
|
Your host: Chris Giese
|
||||||
|
http://www.execpc.com/~geezer/os
|
||||||
|
|
||||||
|
Distribute freely. Last revised on Jan 3, 2002
|
||||||
|
Sources:
|
||||||
|
PORTS.A of Ralf Brown's interrupt list collection
|
||||||
|
repairfaq.org keyboard FAQ(doesn't appear to exsist)
|
||||||
|
Linux source code
|
||||||
|
Test hardware:
|
||||||
|
New Samsung KB3T001SAXAA 104-key keyboard
|
||||||
|
Old Maxi 2186035-00-21 101-key keyboard
|
||||||
|
|
||||||
|
NO WARRANTY. NO GUARANTEE. I have tried to make this information
|
||||||
|
accurate. I don't know if I succeeded. Corrections or additional
|
||||||
|
information would be welcome.
|
||||||
|
|
||||||
|
This is a plain-text document. If you use a word-processor to view
|
||||||
|
it, use a fixed-pitch font (like Courier) so columnar data and
|
||||||
|
ASCII art lines up properly.
|
||||||
|
|
||||||
|
Lessons learned:
|
||||||
|
- Both the 8048 MCU in the keyboard and the 8042 controller
|
||||||
|
on the motherboard accept command bytes.
|
||||||
|
- There is a bit (KCC) in the poorly-named "Command Byte" which
|
||||||
|
seems to enable AT-to-XT scancode conversion (scancode set 2
|
||||||
|
to scancode set 1). After booting DOS, my keyboard uses
|
||||||
|
scancode set 2 with this conversion bit turned on. If I turn
|
||||||
|
the bit off and switch to scancode set 1, operation remains
|
||||||
|
the same.
|
||||||
|
- Scancode set 3 is probably the most elegant, in that it returns
|
||||||
|
a one-byte make code for _every_ key. Unfortunately, not all
|
||||||
|
keyboards support it.
|
||||||
|
- The scancodes of some keys depend on the internal num lock state
|
||||||
|
of the keyboard.
|
||||||
|
|
||||||
|
================================================================
|
||||||
|
KEYBOARD I/O REGISTERS ON THE PC
|
||||||
|
================================================================
|
||||||
|
60h data
|
||||||
|
64h command (write)
|
||||||
|
64h Status (read)
|
||||||
|
|
||||||
|
Bits in Status register (names from Linux source)
|
||||||
|
b7 PERR parity error in data received from keyboard
|
||||||
|
b6 GTO receive timeout
|
||||||
|
b5 transmit timeout (or PS/2 mouse?)
|
||||||
|
b4 keyboard is locked
|
||||||
|
b3 0=60h was the port last accessed, 1=61h was last (?)
|
||||||
|
b2 System Flag status: 0=power-up/reset, 1=selftest OK (?)
|
||||||
|
b1 IBF input buffer full (data from host to keyboard)
|
||||||
|
b0 OBF output buffer full (data from keyboard to host)
|
||||||
|
|
||||||
|
Bits in Output Port of 8042 chip (Table P0383 in PORTS.A)
|
||||||
|
The Output Port is written by controller command D1h,
|
||||||
|
and read by controller command D0h
|
||||||
|
b7 keyboard data output
|
||||||
|
b6 keyboard clock output
|
||||||
|
b5 input buffer NOT full
|
||||||
|
b4 output buffer NOT empty
|
||||||
|
b3 (varies)
|
||||||
|
b2 (varies)
|
||||||
|
b1 A20 gate
|
||||||
|
b0 system reset (THIS BIT SHOULD ALWAYS BE SET TO 1)
|
||||||
|
|
||||||
|
Bits in Input Port of 8042 chip
|
||||||
|
The Input Port is read by controller command C0h
|
||||||
|
b7 keyboard NOT locked
|
||||||
|
b6-b0 (varies)
|
||||||
|
|
||||||
|
Bits in "Command Byte" (confusing name; from Table P0404 in PORTS.A)
|
||||||
|
The "Command Byte" is written by controller command 60h
|
||||||
|
and read by controller command 20h
|
||||||
|
(names from Linux source)
|
||||||
|
b7 (reserved)
|
||||||
|
b6 KCC convert set 2 scancodes to set 1 ("IBM PC compatibility mode")
|
||||||
|
b5 DMS disables PS/2 mouse when set
|
||||||
|
b4 disables keyboard when set
|
||||||
|
b3 ignore keyboard lock switch when set
|
||||||
|
b2 SYS System Flag (same as b2 in Status register, it seems)
|
||||||
|
b1 enables IRQ12 from PS/2 mouse when set
|
||||||
|
b0 EKI enables IRQ1 on keyboard output buffer full
|
||||||
|
|
||||||
|
Result Byte for interface self-tests (Table P0406 in PORTS.A)
|
||||||
|
Returned by controller commands A9h or ABh
|
||||||
|
0 no error
|
||||||
|
1 clock line stuck low
|
||||||
|
2 clock line stuck high
|
||||||
|
3 data line stuck low
|
||||||
|
4 data line stuck high
|
||||||
|
|
||||||
|
================================================================
|
||||||
|
CONTROLLER COMMANDS (from Table P0401 of PORTS.A)
|
||||||
|
================================================================
|
||||||
|
Before writing each byte of these commands to port 64h,
|
||||||
|
poll the status register (port 60h) until bit b1=0.
|
||||||
|
|
||||||
|
20h-2Fh reads byte with address=lower 5 bits of command
|
||||||
|
The byte at address 0 is the "Command Byte".
|
||||||
|
60h-7Fh nn writes byte nn to address=lower 5 bits of command
|
||||||
|
The byte at address 0 is the "Command Byte".
|
||||||
|
A7h disables PS/2 mouse port (MCA only?)
|
||||||
|
A8h enables PS/2 mouse port (MCA only?)
|
||||||
|
A9h self-test mouse interface, returns Result Byte (see above)
|
||||||
|
AAh self-test controller; returns 55h if success, FCh if failure
|
||||||
|
ABh self-test keyboard interface, returns Result Byte (see above)
|
||||||
|
ADh disables keyboard (sets b4 of "Command Byte")
|
||||||
|
AEh enables keyboard (clears b4 of "Command Byte")
|
||||||
|
C0h reads Input Port
|
||||||
|
D0h reads Output Port
|
||||||
|
D1h nn writes Output Port
|
||||||
|
Important: bit 0 (system reset) should always be set here,
|
||||||
|
as the system may hang constantly. To reset the PC, pulse
|
||||||
|
b0 of the Output Port with command FEh instead.
|
||||||
|
DDh disable A20 (Not all systems support this byte)
|
||||||
|
DFh enable A20 (Not all systems support this byte)
|
||||||
|
E0h read test inputs. return value=
|
||||||
|
b1 kbd data
|
||||||
|
b0 kbd clock
|
||||||
|
EDh nn write LEDs. nn=
|
||||||
|
b2 Caps Lock
|
||||||
|
b1 Num Lock
|
||||||
|
b0 Scroll Lock
|
||||||
|
F0h-FFh pulse bit(s) of Output Port low for 6 microseconds.
|
||||||
|
If b0-b3 of the command is low, the corresponding bit
|
||||||
|
in the Output Port will be pulsed low. b0=system reset,
|
||||||
|
and should ALWAYS be PULSED low, never set low constantly.
|
||||||
|
|
||||||
|
================================================================
|
||||||
|
KEYBOARD COMMANDS (from Table P0386 of PORTS.A)
|
||||||
|
================================================================
|
||||||
|
Before writing each byte of these commands to port 60h,
|
||||||
|
poll the status register (port 60h) until bit b1=0.
|
||||||
|
Unless otherwise noted: each command responds with FAh (ACKnowledge)
|
||||||
|
or FEh (Resend) after receiving each byte of the command.
|
||||||
|
|
||||||
|
EDh nn write LEDs, as above
|
||||||
|
EEh echo, keyboard responds with EEh
|
||||||
|
EFh no-operation (reserved)
|
||||||
|
F0h nn selects scancode set nn=1-3 or 0 to return current set
|
||||||
|
F2h read ID. Keyboard responds with ACK (FAh) and two optional
|
||||||
|
ID bytes:
|
||||||
|
(none) AT keyboard
|
||||||
|
83h ABh (?)
|
||||||
|
ABh 41h MF2, translation mode
|
||||||
|
ABh 83h MF2, pass-through mode
|
||||||
|
F3h nn set typematic (auto-repeat) rate/delay. nn=
|
||||||
|
b7 unused
|
||||||
|
b6..5 Repeat delay (00=250 msec ... 11=1000msec)
|
||||||
|
b4..0 Repeat rate (00000=30 Hz ... 11111=2 Hz).
|
||||||
|
F4h clears output buffer, enables keyboard
|
||||||
|
F5h disables keyboard, resets to defaults
|
||||||
|
F6h sets keyboard defaults
|
||||||
|
|
||||||
|
F7h make all keys typematic (auto-repeat) [*]
|
||||||
|
F8h make all keys make-break [*]
|
||||||
|
F9h make all keys make-only [*]
|
||||||
|
FAh make all keys typematic and make-break [*]
|
||||||
|
FBh nn make one key typematic [*]
|
||||||
|
FCh nn make one key make-break [*]
|
||||||
|
FDh nn make one key make-only [*]
|
||||||
|
[*] these commands may work only for
|
||||||
|
scancode set 3; I'm not sure.
|
||||||
|
FEh resend previous scan code
|
||||||
|
FFh reset keyboard CPU, do power-on self-test, return
|
||||||
|
self-test result byte
|
||||||
|
|
||||||
|
non-key status bytes
|
||||||
|
--------------------
|
||||||
|
00h Key detection error or buffer full.
|
||||||
|
AAh Power-on/reset diagnostics successful.
|
||||||
|
E0h (scancode sets 1 and 2) Prefix byte for "gray" keys
|
||||||
|
(keys not on original 83-/84-key keyboard)
|
||||||
|
EEh Sent in response to ECHO command.
|
||||||
|
F0h (scancode sets 2 and 3) Prefix byte for break codes.
|
||||||
|
FAh ACKknowledge; response to most commands.
|
||||||
|
FCh Diagnostics failed (MF keyboard).
|
||||||
|
FDh Diagnostics failed (AT keyboard).
|
||||||
|
The keyboard stops scanning and waits for next command
|
||||||
|
after returning code FCh or FDh
|
||||||
|
FEh Last command was invalid or had parity error; resend it.
|
||||||
|
FFh Key detection error or buffer full.
|
||||||
|
|
||||||
|
====================================================================
|
||||||
|
SCANCODES FOR SCANCODE SET 1 (XT)
|
||||||
|
====================================================================
|
||||||
|
US 104-key keyboard, set 1 scancodes
|
||||||
|
|
||||||
|
|
||||||
|
"Make" code is generated when key is pressed.
|
||||||
|
"Break" code is generated when key is released.
|
||||||
|
Hex value of make code for each key is shown.
|
||||||
|
|
||||||
|
Most keys:
|
||||||
|
one-byte make code = nn
|
||||||
|
one-byte repeat code = nn
|
||||||
|
one-byte break code = 80h + nn
|
||||||
|
|
||||||
|
"Gray" keys (not on original 84-key keyboard):
|
||||||
|
two-byte make code = E0nn
|
||||||
|
two-byte repeat code = E0nn
|
||||||
|
two-byte break code = E0 followed by 80h + nn
|
||||||
|
|
||||||
|
"Gray" keys noted by [1] are NumLock-sensitive.
|
||||||
|
When the keyboard's internal NumLock is active:
|
||||||
|
four-byte make code = E02AE0nn
|
||||||
|
two-byte repeat code = E0nn
|
||||||
|
four-byte break code = E0 followed by 80h + nn followed by E0AA
|
||||||
|
|
||||||
|
____ ___________________ ___________________ ___________________
|
||||||
|
| | | | | | | | | | | | | | | | |
|
||||||
|
|Esc | |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10 |F11 |F12 |
|
||||||
|
| | | | | | | | | | | | | | | | |
|
||||||
|
| 01| | 3B| 3C| 3D| 3E| | 3F| 40| 41| 42| | 43| 44| 57| 58|
|
||||||
|
|____| |____|____|____|____| |____|____|____|____| |____|____|____|____|
|
||||||
|
|
||||||
|
__________________________________________________________________________
|
||||||
|
| | | | | | | | | | | | | | | |
|
||||||
|
|~ |! |@ |# |$ |% |^ |& |* |( |) |_ |+ || |bksp|
|
||||||
|
|` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |\ | |
|
||||||
|
| 29| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 2B| 0E|
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
|
||||||
|
| | | | | | | | | | | | | | |
|
||||||
|
|Tab |Q |W |E |R |T |Y |U |I |O |P |{ |} | |
|
||||||
|
| | | | | | | | | | | |[ |] | |
|
||||||
|
| 0F| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| |
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|____| |
|
||||||
|
| | | | | | | | | | | | | |
|
||||||
|
|Caps|A |S |D |F |G |H |J |K |L |: |" | Enter |
|
||||||
|
| | | | | | | | | | |; |' | |
|
||||||
|
| 3A| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| 1C|
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|______________|
|
||||||
|
| | | | | | | | | | | | |
|
||||||
|
| L Shift |Z |X |C |V |B |N |M |< |> |? | R Shift |
|
||||||
|
| | | | | | | | |, |. |/ | |
|
||||||
|
| 2A| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35| 36|
|
||||||
|
|_________|____|____|____|____|____|____|____|____|____|____|______________|
|
||||||
|
| | | | | | | | |
|
||||||
|
|L Ctrl | L win | L Alt | space | R Alt | R win | menu |R Ctrl |
|
||||||
|
| |[1] | | | |[1] |[1] | |
|
||||||
|
| 1D| E05B| 38| 39| E038| E05C| E05D| E01D|
|
||||||
|
|_______|_______|_______|__________________|_______|_______|_______|_______|
|
||||||
|
|
||||||
|
|
||||||
|
[2] For PrintScreen/SysRq key: make code = E02AE037,
|
||||||
|
repeat code = E037, break code = E0B7E0AA
|
||||||
|
|
||||||
|
[3] The Pause/Break key does not repeat, and it does not
|
||||||
|
generate a break code. Its make code is E11D45E19DC5
|
||||||
|
|
||||||
|
____ ____ ____
|
||||||
|
| | | |
|
||||||
|
|Prt |Scrl|Paus|
|
||||||
|
|Scrn|Lock|Brk |
|
||||||
|
| [2]| 46| [3]|
|
||||||
|
|____|____|____|
|
||||||
|
|
||||||
|
____ ____ ____ ____ ____ ____ ____
|
||||||
|
| | | | | | | | |
|
||||||
|
|Ins |Home|PgUp| |Num |/ |* |- |
|
||||||
|
|[1] |[1] |[1] | |Lock| | | |
|
||||||
|
|E052|E047|E049| | 45|E035| 37| 4A|
|
||||||
|
|____|____|____| |____|____|____|____|
|
||||||
|
| | | | | | | | |
|
||||||
|
|Del |End |PgDn| |7 |8 |9 | |
|
||||||
|
|[1] |[1] |[1] | |Home|(U) |PgUp| |
|
||||||
|
|E053|E04F|E051| | 47| 48| 49| |
|
||||||
|
|____|____|____| |____|____|____| |
|
||||||
|
| | | |+ |
|
||||||
|
|4 |5 |6 | |
|
||||||
|
|(L) | |(R) | |
|
||||||
|
| 4B| 4C| 4D| 4E|
|
||||||
|
____ |____|____|____|____|
|
||||||
|
| | | | | | |
|
||||||
|
|(U) | |1 |2 |3 | |
|
||||||
|
|[1] | |End |(D) |PgDn| |
|
||||||
|
|E048| | 4F| 50| 51|Ent |
|
||||||
|
____|____|____ |____|____|____| |
|
||||||
|
| | | | | | | |
|
||||||
|
|(L) |(D) |(R) | |0 |. | |
|
||||||
|
|[1] |[1] |[1] | |Ins |Del | |
|
||||||
|
|E04B|E050|E04D| | 52| 53|E01C|
|
||||||
|
|____|____|____| |_________|____|____|
|
||||||
|
|
||||||
|
|
||||||
|
code key code key code key code key
|
||||||
|
---- --- ---- --- ---- --- ---- ---
|
||||||
|
01 Esc 0F Tab 1D L Ctrl 2B \|
|
||||||
|
02 1! 10 Q 1E A 2C Z
|
||||||
|
03 2" 11 W 1F S 2D X
|
||||||
|
04 3# 12 E 20 D 2E C
|
||||||
|
05 4$ 13 R 21 F 2F V
|
||||||
|
06 5% 14 T 22 G 30 B
|
||||||
|
07 6^ 15 Y 23 H 31 N
|
||||||
|
08 7& 16 U 24 J 32 M
|
||||||
|
09 8* 17 I 25 K 33 ,<
|
||||||
|
0A 9( 18 O 26 L 34 .>
|
||||||
|
0B 0) 19 P 27 ;: 35 /?
|
||||||
|
0C -_ 1A [{ 28 '" 36 R Shift
|
||||||
|
0D =+ 1B ]} 29 `~ 37 *
|
||||||
|
0E BackSpace 1C Enter 2A L Shift 38 L Alt
|
||||||
|
|
||||||
|
code key code key code key code key
|
||||||
|
---- --- ---- --- ---- --- ---- ---
|
||||||
|
39 Space 41 F7 49 PageUp 9 51 PageDown 3
|
||||||
|
3A CapsLock 42 F8 4A - 52 Insert 0
|
||||||
|
3B F1 43 F9 4B (left) 4 53 Del .
|
||||||
|
3C F2 44 F10 4C 5
|
||||||
|
3D F3 45 NumLock 4D (right) 6 57 F11
|
||||||
|
3E F4 46 ScrollLock 4E + 58 F12
|
||||||
|
3F F5 47 Home 7 4F End 1
|
||||||
|
40 F6 48 (up) 8 50 (down) 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
code key
|
||||||
|
---- ---
|
||||||
|
E01C Enter (on numeric keypad)
|
||||||
|
E01D R Ctrl
|
||||||
|
E02A make code prefix for keyboard internal numlock
|
||||||
|
E02AE037 PrintScreen make code
|
||||||
|
E035 /
|
||||||
|
E037 PrintScreen repeat code
|
||||||
|
E038 R Alt
|
||||||
|
E047 Home
|
||||||
|
E048 (up)
|
||||||
|
E049 PageUp
|
||||||
|
E04B (left)
|
||||||
|
E04D (right)
|
||||||
|
E04F End
|
||||||
|
E050 (down)
|
||||||
|
E051 PageDown
|
||||||
|
E052 Insert
|
||||||
|
E053 Del
|
||||||
|
E05B L Win
|
||||||
|
E05C R Win
|
||||||
|
E05D Menu
|
||||||
|
E0AA break code suffix for keyboard internal numlock
|
||||||
|
E0B7E0AA PrintScreen break code
|
||||||
|
E11D45E19DC5 Pause
|
||||||
|
|
||||||
|
====================================================================
|
||||||
|
SCANCODES FOR SCANCODE SET 2 (AT)
|
||||||
|
====================================================================
|
||||||
|
US 104-key keyboard, set 2 scancodes,
|
||||||
|
8042 AT-to-XT scancode translation OFF
|
||||||
|
|
||||||
|
"Make" code is generated when key is pressed.
|
||||||
|
"Break" code is generated when key is released.
|
||||||
|
Hex value of make code for each key is shown.
|
||||||
|
|
||||||
|
Most keys:
|
||||||
|
one-byte make code = nn
|
||||||
|
one-byte repeat code = nn
|
||||||
|
two-byte break code = F0nn
|
||||||
|
|
||||||
|
"Gray" keys (not on original 84-key keyboard):
|
||||||
|
two-byte make code = E0nn
|
||||||
|
two-byte repeat code = E0nn
|
||||||
|
three-byte break code = E0F0nn
|
||||||
|
|
||||||
|
"Gray" keys noted by [1] are NumLock-sensitive.
|
||||||
|
When the keyboard's internal NumLock is active:
|
||||||
|
four-byte make code = E012E0nn
|
||||||
|
two-byte repeat code = E0nn
|
||||||
|
six-byte break code = E0F0nnE0F012
|
||||||
|
|
||||||
|
____ ___________________ ___________________ ___________________
|
||||||
|
| | | | | | | | | | | | | | | | |
|
||||||
|
|Esc | |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10 |F11 |F12 |
|
||||||
|
| | | | | | | | | | | | | | | | |
|
||||||
|
| 76| | 05| 06| 04| 0C| | 03| 0B| 83| 0A| | 01| 09| 78| 07|
|
||||||
|
|____| |____|____|____|____| |____|____|____|____| |____|____|____|____|
|
||||||
|
|
||||||
|
__________________________________________________________________________
|
||||||
|
| | | | | | | | | | | | | | | |
|
||||||
|
|~ |! |@ |# |$ |% |^ |& |* |( |) |_ |+ || |bksp|
|
||||||
|
|` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |\ | |
|
||||||
|
| 0E| 16| 1E| 26| 25| 2E| 36| 3D| 3E| 46| 45| 4E| 55| 5D| 66|
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
|
||||||
|
| | | | | | | | | | | | | | |
|
||||||
|
|Tab |Q |W |E |R |T |Y |U |I |O |P |{ |} | |
|
||||||
|
| | | | | | | | | | | |[ |] | |
|
||||||
|
| 0D| 15| 1D| 24| 2D| 2C| 35| 3C| 43| 44| 4D| 54| 5B| |
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|____| |
|
||||||
|
| | | | | | | | | | | | | |
|
||||||
|
|Caps|A |S |D |F |G |H |J |K |L |: |" | Enter |
|
||||||
|
| | | | | | | | | | |; |' | |
|
||||||
|
| 58| 1C| 1B| 23| 2B| 34| 33| 3B| 42| 4B| 4C| 52| 5A|
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|______________|
|
||||||
|
| | | | | | | | | | | | |
|
||||||
|
| L Shift |Z |X |C |V |B |N |M |< |> |? | R Shift |
|
||||||
|
| | | | | | | | |, |. |/ | |
|
||||||
|
| 12| 1A| 22| 21| 2A| 32| 31| 3A| 41| 49| 4A| 59|
|
||||||
|
|_________|____|____|____|____|____|____|____|____|____|____|______________|
|
||||||
|
| | | | | | | | |
|
||||||
|
|L Ctrl | L win | L Alt | space | R Alt | R win | menu |R Ctrl |
|
||||||
|
| |[1] | | | |[1] |[1] | |
|
||||||
|
| 14| E01F| 11| 29| E011| E027| E02F| E014|
|
||||||
|
|_______|_______|_______|__________________|_______|_______|_______|_______|
|
||||||
|
|
||||||
|
|
||||||
|
[2] For PrintScreen/SysRq key: make code = E012E07C,
|
||||||
|
repeat code = E07C, break code = E0F07CE0F012
|
||||||
|
|
||||||
|
[3] The Pause/Break key does not repeat, and it does not
|
||||||
|
generate a break code. Its make code is E11477E1F014F077
|
||||||
|
|
||||||
|
____ ____ ____
|
||||||
|
| | | |
|
||||||
|
|Prt |Scrl|Paus|
|
||||||
|
|Scrn|Lock|Brk |
|
||||||
|
| [2]| 7E| [3]|
|
||||||
|
|____|____|____|
|
||||||
|
|
||||||
|
____ ____ ____ ____ ____ ____ ____
|
||||||
|
| | | | | | | | |
|
||||||
|
|Ins |Home|PgUp| |Num |/ |* |- |
|
||||||
|
|[1] |[1] |[1] | |Lock| | | |
|
||||||
|
|E070|E06C|E07D| | 77|E04A| 7C| 7B|
|
||||||
|
|____|____|____| |____|____|____|____|
|
||||||
|
| | | | | | | | |
|
||||||
|
|Del |End |PgDn| |7 |8 |9 | |
|
||||||
|
|[1] |[1] |[1] | |Home|(U) |PgUp| |
|
||||||
|
|E071|E069|E07A| | 6C| 75| 7D| |
|
||||||
|
|____|____|____| |____|____|____| |
|
||||||
|
| | | |+ |
|
||||||
|
|4 |5 |6 | |
|
||||||
|
|(L) | |(R) | |
|
||||||
|
| 6B| 73| 74| 79|
|
||||||
|
____ |____|____|____|____|
|
||||||
|
| | | | | | |
|
||||||
|
|(U) | |1 |2 |3 | |
|
||||||
|
|[1] | |End |(D) |PgDn| |
|
||||||
|
|E075| | 69| 72| 7A|Ent |
|
||||||
|
____|____|____ |____|____|____| |
|
||||||
|
| | | | | | | |
|
||||||
|
|(L) |(D) |(R) | |0 |. | |
|
||||||
|
|[1] |[1] |[1] | |Ins |Del | |
|
||||||
|
|E06B|E072|E074| | 70| 71|E05A|
|
||||||
|
|____|____|____| |_________|____|____|
|
||||||
|
|
||||||
|
|
||||||
|
code key code key code key code key
|
||||||
|
---- --- ---- --- ---- --- ---- ---
|
||||||
|
01 F9 66 BackSpace
|
||||||
|
21 C 41 ,<
|
||||||
|
03 F5 22 X 42 K 69 End 1
|
||||||
|
04 F3 23 D 43 I
|
||||||
|
05 F1 24 E 44 O 6B (left) 4
|
||||||
|
06 F2 25 4$ 45 0) 6C Home 7
|
||||||
|
07 F12 26 3# 46 9(
|
||||||
|
70 Ins 0
|
||||||
|
09 F10 29 Space 49 .> 71 Del .
|
||||||
|
0A F8 2A V 4A /? 72 (down) 2
|
||||||
|
0B F6 2B F 4B L 73 5
|
||||||
|
0C F4 2C T 4C ;: 74 (right) 6
|
||||||
|
0D Tab 2D R 4D P 75 (up) 8
|
||||||
|
0E `~ 2E 5% 4E -_ 76 Esc
|
||||||
|
77 NumLock
|
||||||
|
11 L Alt 31 N 52 '" 78 F11
|
||||||
|
12 L Shift 32 B 79 +
|
||||||
|
33 H 54 [{ 7A PageDown 3
|
||||||
|
14 L Ctrl 34 G 55 =+ 7B -
|
||||||
|
15 Q 35 Y 7C *
|
||||||
|
16 1! 36 6^ 58 CapsLock 7D PageUp 9
|
||||||
|
59 R Shift 7E ScrollLock
|
||||||
|
1A Z 3A M 5A Enter
|
||||||
|
1B S 3B J 5B ]} 83 F7
|
||||||
|
1C A 3C U
|
||||||
|
1D W 3D 7& 5D \|
|
||||||
|
1E 2@ 3E 8*
|
||||||
|
|
||||||
|
code key
|
||||||
|
---- ---
|
||||||
|
E011 R Alt
|
||||||
|
E012E07C PrintScreen make code
|
||||||
|
E014 R Ctrl
|
||||||
|
E01F L Win
|
||||||
|
E027 R Win
|
||||||
|
E02F Menu
|
||||||
|
E04A /
|
||||||
|
E05A Enter (on numeric keypad)
|
||||||
|
E069 End
|
||||||
|
E06B Left
|
||||||
|
E06C Home
|
||||||
|
E070 Ins
|
||||||
|
E071 Del
|
||||||
|
E072 (down)
|
||||||
|
E074 (right)
|
||||||
|
E075 (up)
|
||||||
|
E07A PageDown
|
||||||
|
E07C PrintScreen repeat code
|
||||||
|
E07D PageUp
|
||||||
|
E0F07CE0F012 PrintScreen break code
|
||||||
|
E11477E1F014F077 Pause
|
||||||
|
|
||||||
|
====================================================================
|
||||||
|
SCANCODES FOR SCANCODE SET 3
|
||||||
|
====================================================================
|
||||||
|
US 104-key keyboard, set 3 scancodes
|
||||||
|
|
||||||
|
|
||||||
|
"Make" code is generated when key is pressed.
|
||||||
|
"Break" code is generated when key is released.
|
||||||
|
Hex value of make code for each key is shown.
|
||||||
|
|
||||||
|
All keys:
|
||||||
|
one-byte make code = nn
|
||||||
|
one-byte repeat code = nn
|
||||||
|
two-byte break code = F0nn
|
||||||
|
|
||||||
|
When operating in scancode set 3, the keyboard
|
||||||
|
does not maintain an internal NumLock state.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
____ ___________________ ___________________ ___________________
|
||||||
|
| | | | | | | | | | | | | | | | |
|
||||||
|
|Esc | |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10 |F11 |F12 |
|
||||||
|
| | | | | | | | | | | | | | | | |
|
||||||
|
| 08| | 07| 0F| 17| 1F| | 27| 2F| 37| 3F| | 47| 4F| 56| 5E|
|
||||||
|
|____| |____|____|____|____| |____|____|____|____| |____|____|____|____|
|
||||||
|
|
||||||
|
__________________________________________________________________________
|
||||||
|
| | | | | | | | | | | | | | | |
|
||||||
|
|~ |! |@ |# |$ |% |^ |& |* |( |) |_ |+ || |bksp|
|
||||||
|
|` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |\ | |
|
||||||
|
| 0E| 16| 1E| 26| 25| 2E| 36| 3D| 3E| 46| 45| 4E| 55| 5C| 66|
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
|
||||||
|
| | | | | | | | | | | | | | |
|
||||||
|
|Tab |Q |W |E |R |T |Y |U |I |O |P |{ |} | |
|
||||||
|
| | | | | | | | | | | |[ |] | |
|
||||||
|
| 0D| 15| 1D| 24| 2D| 2C| 35| 3C| 43| 44| 4D| 54| 5B| |
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|____| |
|
||||||
|
| | | | | | | | | | | | | |
|
||||||
|
|Caps|A |S |D |F |G |H |J |K |L |: |" | Enter |
|
||||||
|
| | | | | | | | | | |; |' | |
|
||||||
|
| 14| 1C| 1B| 23| 2B| 34| 33| 3B| 42| 4B| 4C| 52| 5A|
|
||||||
|
|____|____|____|____|____|____|____|____|____|____|____|____|______________|
|
||||||
|
| | | | | | | | | | | | |
|
||||||
|
| L Shift |Z |X |C |V |B |N |M |< |> |? | R Shift |
|
||||||
|
| | | | | | | | |, |. |/ | |
|
||||||
|
| 12| 1A| 22| 21| 2A| 32| 31| 3A| 41| 49| 4A| 59|
|
||||||
|
|_________|____|____|____|____|____|____|____|____|____|____|______________|
|
||||||
|
| | | | | | | | |
|
||||||
|
|L Ctrl | L win | L Alt | space | R Alt | R win | menu |R Ctrl |
|
||||||
|
| | | | | | | | |
|
||||||
|
| 11| 8B| 19| 29| 39| 8C| 8D| 58|
|
||||||
|
|_______|_______|_______|__________________|_______|_______|_______|_______|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
____ ____ ____
|
||||||
|
| | | |
|
||||||
|
|Prt |Scrl|Paus|
|
||||||
|
|Scrn|Lock|Brk |
|
||||||
|
| 57| 5F| 62|
|
||||||
|
|____|____|____|
|
||||||
|
|
||||||
|
____ ____ ____ ____ ____ ____ ____
|
||||||
|
| | | | | | | | |
|
||||||
|
|Ins |Home|PgUp| |Num |/ |* |- |
|
||||||
|
| | | | |Lock| | | |
|
||||||
|
| 67| 6E| 6F| | 76| 77| 7E| 84|
|
||||||
|
|____|____|____| |____|____|____|____|
|
||||||
|
| | | | | | | | |
|
||||||
|
|Del |End |PgDn| |7 |8 |9 | |
|
||||||
|
| | | | |Home|(U) |PgUp| |
|
||||||
|
| 64| 65| 6D| | 6C| 75| 7D| |
|
||||||
|
|____|____|____| |____|____|____| |
|
||||||
|
| | | |+ |
|
||||||
|
|4 |5 |6 | |
|
||||||
|
|(L) | |(R) | |
|
||||||
|
| 6B| 73| 74| 7C|
|
||||||
|
____ |____|____|____|____|
|
||||||
|
| | | | | | |
|
||||||
|
|(U) | |1 |2 |3 | |
|
||||||
|
| | |End |(D) |PgDn| |
|
||||||
|
| 63| | 69| 72| 7A|Ent |
|
||||||
|
____|____|____ |____|____|____| |
|
||||||
|
| | | | | | | |
|
||||||
|
|(L) |(D) |(R) | |0 |. | |
|
||||||
|
| | | | |Ins |Del | |
|
||||||
|
| 61| 60| 6A| | 70| 71| 79|
|
||||||
|
|____|____|____| |_________|____|____|
|
||||||
|
|
||||||
|
|
||||||
|
code key code key code key code key
|
||||||
|
---- --- ---- --- ---- --- ---- ---
|
||||||
|
07 F1 2A V 4A /? 6B (left) 4
|
||||||
|
08 Esc 2B F 4B L 6C Home 7
|
||||||
|
2C T 4C ;: 6D PageDown
|
||||||
|
0D Tab 2D R 4D P 6E Home
|
||||||
|
0E `~ 2E 5% 4E -_ 6F PageUp
|
||||||
|
0F F2 2F F6 4F F10 70 Ins 0
|
||||||
|
71 Del .
|
||||||
|
11 L Ctrl 31 N 52 '" 72 (down) 2
|
||||||
|
12 L Shift 32 B 73 5
|
||||||
|
33 H 54 [{ 74 (right) 6
|
||||||
|
14 CapsLock 34 G 55 =+ 75 (up) 8
|
||||||
|
15 Q 35 Y 56 F11 76 NumLock
|
||||||
|
16 1! 36 6^ 57 PrintScr 77 /
|
||||||
|
17 F3 37 F7 58 R Ctrl
|
||||||
|
59 R Shift 79 Enter (on numeric keypad)
|
||||||
|
19 L Alt 39 R Alt 5A Enter 7A PageDown 3
|
||||||
|
1A Z 3A M 5B ]}
|
||||||
|
1B S 3B J 5C \| 7C +
|
||||||
|
1C A 3C U 7D PageUp 9
|
||||||
|
1D W 3D 7& 5E F12 7E *
|
||||||
|
1E 2@ 3E 8* 5F ScrollLock
|
||||||
|
1F F4 3F F8 60 (down) 84 -
|
||||||
|
61 (left)
|
||||||
|
21 C 41 ,< 62 Pause 8B L Win
|
||||||
|
22 X 42 K 63 (up) 8C R Win
|
||||||
|
23 D 43 I 64 Del 8D Menu
|
||||||
|
24 E 44 O 65 End
|
||||||
|
25 4$ 45 0) 66 BackSpace
|
||||||
|
26 3# 46 9( 67 Ins
|
||||||
|
27 F5 47 F9
|
||||||
|
69 End 1
|
||||||
|
29 Space 49 .> 6A (right)
|
||||||
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.
Binary file not shown.
@@ -0,0 +1,955 @@
|
|||||||
|
1 8 0 0 0 0 0 0 0 0
|
||||||
|
1 8 0 0 0 0 0 0 0 -1
|
||||||
|
1 8 0 0 0 0 0 0 0 -2
|
||||||
|
1 8 0 0 0 0 0 0 0 -3
|
||||||
|
1 8 0 0 0 0 0 0 0 -4
|
||||||
|
1 8 0 0 0 0 0 0 0 -5
|
||||||
|
1 8 0 0 0 0 0 0 0 -6
|
||||||
|
1 8 0 0 0 0 0 0 0 -7
|
||||||
|
1 8 0 0 0 0 0 0 0 -8
|
||||||
|
1 8 0 0 0 0 0 0 0 -9
|
||||||
|
1 8 0 0 0 0 0 0 0 -10
|
||||||
|
1 8 0 0 0 0 0 0 0 -11
|
||||||
|
1 8 0 0 0 0 0 0 0 -12
|
||||||
|
1 8 0 0 0 0 0 0 0 -13
|
||||||
|
1 8 0 0 0 0 0 0 0 -14
|
||||||
|
1 8 0 0 0 0 0 0 0 -15
|
||||||
|
1 8 0 0 0 0 0 0 0 -16
|
||||||
|
1 8 0 0 0 0 0 0 0 -17
|
||||||
|
1 8 0 0 0 0 0 0 0 -18
|
||||||
|
1 8 0 0 0 0 0 0 0 -19
|
||||||
|
1 8 0 0 0 0 0 0 0 -20
|
||||||
|
1 8 0 0 0 0 0 0 0 -21
|
||||||
|
1 8 0 0 0 0 0 0 0 -22
|
||||||
|
1 8 0 0 0 0 0 0 0 -23
|
||||||
|
1 8 0 0 0 0 0 0 0 -24
|
||||||
|
1 8 0 0 0 0 0 0 0 -25
|
||||||
|
1 8 0 0 0 0 0 0 0 -26
|
||||||
|
1 8 0 0 0 0 0 0 0 -27
|
||||||
|
1 8 0 0 0 0 0 0 0 -28
|
||||||
|
1 8 0 0 0 0 0 0 0 -29
|
||||||
|
1 8 0 0 0 0 0 0 0 -30
|
||||||
|
1 8 0 0 0 0 0 0 0 -31
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
1 8
|
||||||
|
1 1 1 1 1 0 1 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
0 1 0 1
|
||||||
|
0 1 0 1
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
0 0 1 0 1 0 0
|
||||||
|
0 0 1 0 1 0 0
|
||||||
|
1 1 1 1 1 1 1
|
||||||
|
0 0 1 0 1 0 0
|
||||||
|
1 1 1 1 1 1 1
|
||||||
|
0 0 1 0 1 0 0
|
||||||
|
0 0 1 0 1 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 1 1 1
|
||||||
|
1 0 1 0 0
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 1 0 1
|
||||||
|
1 1 1 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 0 0 0
|
||||||
|
1 1 0 0 1
|
||||||
|
1 1 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 0 1 1
|
||||||
|
1 0 0 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
6 8
|
||||||
|
0 0 1 1 0 0
|
||||||
|
0 1 0 1 0 0
|
||||||
|
0 0 1 0 0 0
|
||||||
|
0 1 0 1 0 0
|
||||||
|
1 0 0 0 1 1
|
||||||
|
1 0 0 0 1 0
|
||||||
|
0 1 1 1 0 1
|
||||||
|
0 0 0 0 0 0
|
||||||
|
|
||||||
|
1 8
|
||||||
|
1 1 0 0 0 0 0 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
0 0 1
|
||||||
|
0 1 0
|
||||||
|
1 0 0
|
||||||
|
1 0 0
|
||||||
|
1 0 0
|
||||||
|
0 1 0
|
||||||
|
0 0 1
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
1 0 0
|
||||||
|
0 1 0
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
0 1 0
|
||||||
|
1 0 0
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
1 0 0 1 0 0 1
|
||||||
|
0 1 0 1 0 1 0
|
||||||
|
0 0 1 1 1 0 0
|
||||||
|
0 1 0 1 0 1 0
|
||||||
|
1 0 0 1 0 0 1
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
1 1 1 1 1 1 1
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
2 8
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
0 1
|
||||||
|
1 0
|
||||||
|
|
||||||
|
6 8
|
||||||
|
0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0
|
||||||
|
1 1 1 1 1 1
|
||||||
|
0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0
|
||||||
|
|
||||||
|
2 8
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
0 0 0 0 0 0 1
|
||||||
|
0 0 0 0 0 1 0
|
||||||
|
0 0 0 0 1 0 0
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
0 0 1 0 0 0 0
|
||||||
|
0 1 0 0 0 0 0
|
||||||
|
1 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 1 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
0 1 0
|
||||||
|
1 1 0
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
1 1 1
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 1
|
||||||
|
0 0 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 0 0 0
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 1
|
||||||
|
0 0 1 1 0
|
||||||
|
0 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
6 8
|
||||||
|
0 0 0 1 1 0
|
||||||
|
0 0 1 0 1 0
|
||||||
|
0 1 0 0 1 0
|
||||||
|
1 0 0 0 1 0
|
||||||
|
1 1 1 1 1 1
|
||||||
|
0 0 0 0 1 0
|
||||||
|
0 0 0 0 1 0
|
||||||
|
0 0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 1 1
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 1 1 1 0
|
||||||
|
0 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 0
|
||||||
|
1 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 1
|
||||||
|
0 0 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 0 0 0
|
||||||
|
0 1 0 0 0
|
||||||
|
0 1 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 1
|
||||||
|
0 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
2 8
|
||||||
|
0 0
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
0 0
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
|
||||||
|
2 8
|
||||||
|
0 0
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
0 0
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
0 1
|
||||||
|
1 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 1
|
||||||
|
0 0 1 0
|
||||||
|
0 1 0 0
|
||||||
|
1 0 0 0
|
||||||
|
0 1 0 0
|
||||||
|
0 0 1 0
|
||||||
|
0 0 0 1
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
1 0 0 0
|
||||||
|
0 1 0 0
|
||||||
|
0 0 1 0
|
||||||
|
0 0 0 1
|
||||||
|
0 0 1 0
|
||||||
|
0 1 0 0
|
||||||
|
1 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 1
|
||||||
|
0 0 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 1 1 1
|
||||||
|
1 0 1 0 1
|
||||||
|
1 0 1 1 1
|
||||||
|
1 0 0 0 0
|
||||||
|
0 1 1 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 1 1 1 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 1 1
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 1 1 1 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 1 1
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 1 1 1 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 1 1 1 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
1 1 1
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
1 1 1
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 1 1 1
|
||||||
|
0 0 0 1 0
|
||||||
|
0 0 0 1 0
|
||||||
|
0 0 0 1 0
|
||||||
|
0 0 0 1 0
|
||||||
|
1 0 0 1 0
|
||||||
|
0 1 1 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 1 0
|
||||||
|
1 1 1 0 0
|
||||||
|
1 0 0 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
1 1 0 0 0 1 1
|
||||||
|
1 0 1 0 1 0 1
|
||||||
|
1 0 0 1 0 0 1
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 1 0 0 1
|
||||||
|
1 0 1 0 1
|
||||||
|
1 0 0 1 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
1 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 1 1 0
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 1 1
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 0 0
|
||||||
|
1 0 0 1 0
|
||||||
|
1 0 0 1 0
|
||||||
|
1 1 1 0 0
|
||||||
|
1 0 1 0 0
|
||||||
|
1 0 0 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 1 1 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 0
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
0 1 0 1 0 1 0
|
||||||
|
0 1 0 1 0 1 0
|
||||||
|
0 0 1 0 1 0 0
|
||||||
|
0 0 1 0 1 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 0 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 1 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 1
|
||||||
|
0 0 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 0 0 0
|
||||||
|
1 0 0 0 0
|
||||||
|
1 1 1 1 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
1 1 1
|
||||||
|
1 0 0
|
||||||
|
1 0 0
|
||||||
|
1 0 0
|
||||||
|
1 0 0
|
||||||
|
1 0 0
|
||||||
|
1 1 1
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
1 0 0 0 0 0 0
|
||||||
|
0 1 0 0 0 0 0
|
||||||
|
0 0 1 0 0 0 0
|
||||||
|
0 0 0 1 0 0 0
|
||||||
|
0 0 0 0 1 0 0
|
||||||
|
0 0 0 0 0 1 0
|
||||||
|
0 0 0 0 0 0 1
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
1 1 1
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
1 1 1
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 0 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
1 1 1 1 1
|
||||||
|
|
||||||
|
2 8
|
||||||
|
1 0
|
||||||
|
0 1
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
|
||||||
|
|
||||||
|
6 8
|
||||||
|
0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0
|
||||||
|
0 1 1 1 0 0
|
||||||
|
0 0 0 0 1 0
|
||||||
|
0 1 1 1 1 0
|
||||||
|
1 0 0 0 1 0
|
||||||
|
0 1 1 1 0 1
|
||||||
|
0 0 0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 0
|
||||||
|
1 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 1 1 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 1
|
||||||
|
0 1 1 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 1
|
||||||
|
0 0 0 1
|
||||||
|
0 1 1 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0 1 1 1
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 1 1 1
|
||||||
|
1 0 0 0
|
||||||
|
0 1 1 1
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4
|
||||||
|
0 0 1 0
|
||||||
|
0 1 0 1
|
||||||
|
0 1 0 0
|
||||||
|
1 1 1 0
|
||||||
|
0 1 0 0
|
||||||
|
0 1 0 0
|
||||||
|
0 1 0 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0 1 1 1
|
||||||
|
0 0 0 1
|
||||||
|
1 1 1 1
|
||||||
|
|
||||||
|
4 8
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 0
|
||||||
|
1 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
1 8
|
||||||
|
1 0 1 1 1 1 1 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
0 0 1
|
||||||
|
0 0 0
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
0 0 1
|
||||||
|
1 1 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 1 0
|
||||||
|
1 1 0 0
|
||||||
|
1 0 1 0
|
||||||
|
1 0 0 1
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
2 8
|
||||||
|
1 0
|
||||||
|
1 0
|
||||||
|
1 0
|
||||||
|
1 0
|
||||||
|
1 0
|
||||||
|
1 0
|
||||||
|
1 1
|
||||||
|
0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
0 1 1 0 1 1 0
|
||||||
|
1 0 0 1 0 0 1
|
||||||
|
1 0 0 1 0 0 1
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
1 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0 1 1 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
1 1 1 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 1 1 0
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 1 1 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0 1 1 1
|
||||||
|
0 0 0 1
|
||||||
|
0 0 0 1
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
1 0 1 1
|
||||||
|
1 1 0 0
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 0
|
||||||
|
1 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
0 1 1 1
|
||||||
|
1 0 0 0
|
||||||
|
0 1 1 0
|
||||||
|
0 0 0 1
|
||||||
|
1 1 1 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 1 0 0
|
||||||
|
0 1 0 0
|
||||||
|
1 1 1 1
|
||||||
|
0 1 0 0
|
||||||
|
0 1 0 0
|
||||||
|
0 1 0 1
|
||||||
|
0 0 1 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0 1 1 0
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
1 0 0 0 0 0 1
|
||||||
|
1 0 0 1 0 0 1
|
||||||
|
0 1 0 1 0 1 0
|
||||||
|
0 0 1 0 1 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
5 8
|
||||||
|
0 0 0 0 0
|
||||||
|
0 0 0 0 0
|
||||||
|
1 0 0 0 1
|
||||||
|
0 1 0 1 0
|
||||||
|
0 0 1 0 0
|
||||||
|
0 1 0 1 0
|
||||||
|
1 0 0 0 1
|
||||||
|
0 0 0 0 0
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
1 0 0 1
|
||||||
|
0 1 1 1
|
||||||
|
0 0 0 1
|
||||||
|
1 1 1 1
|
||||||
|
|
||||||
|
4 8
|
||||||
|
0 0 0 0
|
||||||
|
0 0 0 0
|
||||||
|
1 1 1 1
|
||||||
|
0 0 0 1
|
||||||
|
0 1 1 0
|
||||||
|
1 0 0 0
|
||||||
|
1 1 1 1
|
||||||
|
0 0 0 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
0 0 1
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
1 0 0
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
0 0 1
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
1 8
|
||||||
|
1 1 1 1 1 1 1 0
|
||||||
|
|
||||||
|
3 8
|
||||||
|
1 0 0
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
0 0 1
|
||||||
|
0 1 0
|
||||||
|
0 1 0
|
||||||
|
1 0 0
|
||||||
|
0 0 0
|
||||||
|
|
||||||
|
7 8
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
0 1 1 0 0 0 0
|
||||||
|
1 0 0 1 0 0 1
|
||||||
|
0 0 0 0 1 1 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0
|
||||||
@@ -0,0 +1,270 @@
|
|||||||
|
# User sets these
|
||||||
|
CC = gcc
|
||||||
|
ASM = nasm
|
||||||
|
CURDIR = /media/6C9EE8DF9EE8A336/ctaos
|
||||||
|
|
||||||
|
# Other parameters & paths used
|
||||||
|
LSCRIPT = SysCore/objects/linker.ld
|
||||||
|
OBJ = Build
|
||||||
|
|
||||||
|
CCPARAM = -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./SysCore/include -c
|
||||||
|
ASMPARAMobj = -f aout
|
||||||
|
ASMPARAMbin = -f bin
|
||||||
|
|
||||||
|
#.PHONY : FORCE
|
||||||
|
#FORCE :#
|
||||||
|
# @echo -e "\e[1;4m\e[36mC\e[31mT\e[32mA \e[37mOperating System v0.1\e[0"
|
||||||
|
|
||||||
|
# Build final floppy image
|
||||||
|
ctaos.img : $(OBJ)bootload.bin $(OBJ)stage2.cta $(OBJ)kernel.bin
|
||||||
|
@echo -e "\e[1;32m[ 99%]\e[0m Making floppy image"
|
||||||
|
dd bs=512 count=2880 if=/dev/zero of=ctaos.img
|
||||||
|
mkfs.msdos ctaos.img
|
||||||
|
dd bs=512 count=1 conv=notrunc if=$(OBJ)bootload.bin of=ctaos.img
|
||||||
|
sudo mkdir /media/floppy1/
|
||||||
|
sudo mount -o loop ctaos.img /media/floppy1/
|
||||||
|
sudo cp $(OBJ)stage2.cta /media/floppy1
|
||||||
|
sudo cp $(OBJ)kernel.bin /media/floppy1
|
||||||
|
sudo umount /media/floppy1/
|
||||||
|
sudo rm -r /media/floppy1/
|
||||||
|
|
||||||
|
|
||||||
|
# Build Bootloader: Stage 1
|
||||||
|
$(OBJ)bootload.bin : SysBoot/stage1/bootload.asm
|
||||||
|
echo -e "\e[1;32m[ 4%]\e[0m BOOTLOADER :: stage 1"
|
||||||
|
@$(ASM) $(ASMPARAMbin) SysBoot/stage1/bootload.asm -o $(OBJ)bootload.bin
|
||||||
|
|
||||||
|
# Build Bootloader: Stage 2
|
||||||
|
$(OBJ)stage2.cta : SysBoot/stage2/stage2.asm \
|
||||||
|
SysBoot/stage2/a20.inc \
|
||||||
|
SysBoot/stage2/bootinfo.inc \
|
||||||
|
SysBoot/stage2/common.inc \
|
||||||
|
SysBoot/stage2/fat12.inc \
|
||||||
|
SysBoot/stage2/floppy16.inc \
|
||||||
|
SysBoot/stage2/gdt.inc \
|
||||||
|
SysBoot/stage2/getdata.inc \
|
||||||
|
SysBoot/stage2/memory.inc \
|
||||||
|
SysBoot/stage2/paging.inc \
|
||||||
|
SysBoot/stage2/stdio.inc
|
||||||
|
@echo -e "\e[1;32m[ 8%]\e[0m BOOTLOADER :: stage 2"
|
||||||
|
@$(ASM) $(ASMPARAMbin) -I./SysBoot/stage2/ -o $(OBJ)stage2.cta SysBoot/stage2/stage2.asm
|
||||||
|
|
||||||
|
# Build KERNEL:
|
||||||
|
$(OBJ)kernel.bin : $(OBJ)/loader.o \
|
||||||
|
$(OBJ)/main.o \
|
||||||
|
$(OBJ)/lib-conio.o \
|
||||||
|
$(OBJ)/lib-ctype.o \
|
||||||
|
$(OBJ)/mmngr-asm.o \
|
||||||
|
$(OBJ)/mmngr-phys.o \
|
||||||
|
$(OBJ)/mmngr-virt.o \
|
||||||
|
$(OBJ)/mmngr-lib-pde.o \
|
||||||
|
$(OBJ)/mmngr-lib-pte.o \
|
||||||
|
$(OBJ)/shell.o \
|
||||||
|
$(OBJ)/lib-stdlib.o \
|
||||||
|
$(OBJ)/lib-string.o \
|
||||||
|
$(OBJ)/lib-system.o \
|
||||||
|
$(OBJ)/lib-time.o \
|
||||||
|
$(OBJ)/driver-bsod.o \
|
||||||
|
$(OBJ)/driver-cpu.o \
|
||||||
|
$(OBJ)/driver-dma.o \
|
||||||
|
$(OBJ)/driver-drivers.o \
|
||||||
|
$(OBJ)/driver-floppy.o \
|
||||||
|
$(OBJ)/driver-gdt.o \
|
||||||
|
$(OBJ)/driver-gdt-asm.o \
|
||||||
|
$(OBJ)/driver-idt.o \
|
||||||
|
$(OBJ)/driver-idt-asm.o \
|
||||||
|
$(OBJ)/driver-isrs.o \
|
||||||
|
$(OBJ)/driver-isrs-asm.o \
|
||||||
|
$(OBJ)/driver-irq.o \
|
||||||
|
$(OBJ)/driver-irq-asm.o \
|
||||||
|
$(OBJ)/driver-keyboard.o \
|
||||||
|
$(OBJ)/driver-fat.o \
|
||||||
|
$(OBJ)/driver-pic.o \
|
||||||
|
$(OBJ)/driver-pit.o \
|
||||||
|
$(OBJ)/video-vga03h.o
|
||||||
|
ld -T SysCore/link.ld
|
||||||
|
|
||||||
|
# ---------- Kernel components ---------- #
|
||||||
|
|
||||||
|
# Build assembly sources:
|
||||||
|
$(OBJ)/loader.o : SysCore/loader.asm
|
||||||
|
@ echo -e "\e[1;33m[ 9%]\e[0m Assembly kernel loader"
|
||||||
|
@$(ASM) $(ASMPARAMobj) -o $(OBJ)/loader.o SysCore/loader.asm
|
||||||
|
|
||||||
|
$(OBJ)/driver-gdt-asm.o : SysCore/drivers/cpu/gdt/gdt.asm
|
||||||
|
@echo -e "\e[1;33m[ 10%]\e[0m Assembly code for GDT"
|
||||||
|
@$(ASM) $(ASMPARAMobj) -o $(OBJ)/driver-gdt-asm.o SysCore/drivers/cpu/gdt/gdt.asm
|
||||||
|
|
||||||
|
$(OBJ)/driver-idt-asm.o : SysCore/drivers/cpu/idt/idt.asm
|
||||||
|
@echo -e "\e[1;33m[ 11%]\e[0m Assembly code for IDT"
|
||||||
|
@$(ASM) $(ASMPARAMobj) -o $(OBJ)/driver-idt-asm.o SysCore/drivers/cpu/idt/idt.asm
|
||||||
|
|
||||||
|
$(OBJ)/driver-irq-asm.o : SysCore/drivers/cpu/irq/irq.asm
|
||||||
|
@echo -e "\e[1;33m[ 12%]\e[0m Assembly code for IRQ"
|
||||||
|
@$(ASM) $(ASMPARAMobj) -o $(OBJ)/driver-irq-asm.o SysCore/drivers/cpu/irq/irq.asm
|
||||||
|
|
||||||
|
$(OBJ)/driver-isrs-asm.o : SysCore/drivers/cpu/isrs/isrs.asm
|
||||||
|
@echo -e "\e[1;33m[ 13%]\e[0m Assembly code for ISRs"
|
||||||
|
@$(ASM) $(ASMPARAMobj) -o $(OBJ)/driver-isrs-asm.o SysCore/drivers/cpu/isrs/isrs.asm
|
||||||
|
|
||||||
|
|
||||||
|
# Build MAIN function
|
||||||
|
$(OBJ)/main.o : SysCore/main.c SysCore/include/string.h \
|
||||||
|
SysCore/include/system.h SysCore/include/conio.h \
|
||||||
|
SysCore/drivers/drivers.h SysCore/include/time.h \
|
||||||
|
SysCore/include/bootinfo.h SysCore/memory/mmngr_ph.h \
|
||||||
|
SysCore/memory/mmngr_vi.h SysCore/video/vga03h.h
|
||||||
|
@echo -e "\e[1;32m[ 14%]\e[0m MAIN C Function"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/main.o SysCore/main.c
|
||||||
|
|
||||||
|
# Build SHELL
|
||||||
|
$(OBJ)/shell.o : SysCore/shell/shell.c SysCore/shell/apps.h \
|
||||||
|
SysCore/include/system.h SysCore/include/conio.h \
|
||||||
|
SysCore/drivers/drivers.h SysCore/include/time.h \
|
||||||
|
SysCore/memory/mmngr_ph.h SysCore/drivers/keyboard.h \
|
||||||
|
SysCore/drivers/cpu/cpu.h SysCore/include/drivers/floppy.h \
|
||||||
|
SysCore/drivers/filesys/fat.h
|
||||||
|
@echo -e "\e[1;34m[ 15%]\e[0m Shell"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/shell.o SysCore/shell/shell.c
|
||||||
|
|
||||||
|
# Build LIBRARIES
|
||||||
|
$(OBJ)/lib-conio.o : SysCore/lib/conio.c \
|
||||||
|
SysCore/include/drivers/keyboard.h SysCore/include/stdarg.h \
|
||||||
|
SysCore/include/conio.h SysCore/include/stdlib.h \
|
||||||
|
SysCore/include/string.h SysCore/include/ctype.h \
|
||||||
|
SysCore/memory/mmngr_ph.h
|
||||||
|
@echo -e "\e[1;34m[ 16%]\e[0m Libraries: conio"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/lib-conio.o SysCore/lib/conio.c
|
||||||
|
|
||||||
|
$(OBJ)/lib-ctype.o : SysCore/lib/ctype.c SysCore/include/ctype.h
|
||||||
|
@echo -e "\e[1;34m[ 17%]\e[0m Libraries: ctype"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/lib-ctype.o SysCore/lib/ctype.c
|
||||||
|
|
||||||
|
$(OBJ)/lib-stdlib.o : SysCore/lib/stdlib.c SysCore/include/stdlib.h \
|
||||||
|
SysCore/include/ctype.h
|
||||||
|
@echo -e "\e[1;34m[ 18%]\e[0m Libraries: stdlib"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/lib-stdlib.o SysCore/lib/stdlib.c
|
||||||
|
|
||||||
|
$(OBJ)/lib-string.o : SysCore/lib/string.c SysCore/include/string.h
|
||||||
|
@echo -e "\e[1;32m[ 19%]\e[0m Libraries: string"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/lib-string.o SysCore/lib/string.c
|
||||||
|
|
||||||
|
$(OBJ)/lib-system.o : SysCore/lib/system.c SysCore/include/system.h
|
||||||
|
@echo -e "\e[1;34m[ 20%]\e[0m Libraries: system"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/lib-system.o SysCore/lib/system.c
|
||||||
|
|
||||||
|
$(OBJ)/lib-time.o : SysCore/lib/time.c SysCore/include/time.h \
|
||||||
|
SysCore/include/system.h
|
||||||
|
@echo -e "\e[1;34m[ 21%]\e[0m Libraries: time"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/lib-time.o SysCore/lib/time.c
|
||||||
|
|
||||||
|
|
||||||
|
# Build Memory Manager
|
||||||
|
$(OBJ)/mmngr-asm.o : SysCore/memory/mmngr.asm
|
||||||
|
@echo -e "\e[1;36m[ 22%]\e[0m Memory manager assembly code"
|
||||||
|
@$(ASM) $(ASMPARAMobj) -o $(OBJ)/mmngr-asm.o SysCore/memory/mmngr.asm
|
||||||
|
|
||||||
|
$(OBJ)/mmngr-phys.o : SysCore/memory/mmngr_ph.c SysCore/memory/mmngr_ph.h
|
||||||
|
@echo -e "\e[1;36m[ 22%]\e[0m Physical memory manager"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/mmngr-phys.o SysCore/memory/mmngr_ph.c
|
||||||
|
|
||||||
|
$(OBJ)/mmngr-virt.o : SysCore/memory/mmngr_vi.c SysCore/memory/mmngr_vi.h \
|
||||||
|
SysCore/memory/mmngr_ph.h
|
||||||
|
@echo -e "\e[1;36m[ 23%]\e[0m Virtual memory manager"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/mmngr-virt.o SysCore/memory/mmngr_vi.c
|
||||||
|
|
||||||
|
$(OBJ)/mmngr-lib-pde.o : SysCore/memory/lib/pde.c SysCore/memory/lib/pde.h
|
||||||
|
@echo -e "\e[1;36m[ 24%]\e[0m Memory manager libraries: PDE"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/mmngr-lib-pde.o SysCore/memory/lib/pde.c
|
||||||
|
|
||||||
|
$(OBJ)/mmngr-lib-pte.o : SysCore/memory/lib/pte.c SysCore/memory/lib/pte.h
|
||||||
|
@echo -e "\e[1;36m[ 25%]\e[0m Memory manager libraries: PTE"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/mmngr-lib-pte.o SysCore/memory/lib/pte.c
|
||||||
|
|
||||||
|
|
||||||
|
# Build drivers
|
||||||
|
$(OBJ)/driver-drivers.o : SysCore/drivers/drivers.c SysCore/include/system.h \
|
||||||
|
SysCore/drivers/cpu/cpu.h SysCore/drivers/clock/clock.h \
|
||||||
|
SysCore/drivers/floppy/floppy.h SysCore/include/drivers/keyboard.h
|
||||||
|
@echo -e "\e[1;35m[ 26%]\e[0m Driver manager"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-drivers.o SysCore/drivers/drivers.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-bsod.o : SysCore/drivers/BSOD.c SysCore/include/system.h \
|
||||||
|
SysCore/include/conio.h
|
||||||
|
@echo -e "\e[1;35m[ 27%]\e[0m Kernel panic screen"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-bsod.o SysCore/drivers/BSOD.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-cpu.o : SysCore/drivers/cpu/cpu.c SysCore/include/system.h \
|
||||||
|
SysCore/drivers/cpu/cpu.h SysCore/drivers/cpu/gdt/gdt.h \
|
||||||
|
SysCore/drivers/cpu/idt/idt.h SysCore/drivers/cpu/irq/irq.h \
|
||||||
|
SysCore/drivers/cpu/isrs/isrs.h
|
||||||
|
@echo -e "\e[1;35m[ 28%]\e[0m CPU modules"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-cpu.o SysCore/drivers/cpu/cpu.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-gdt.o : SysCore/drivers/cpu/gdt/gdt.c SysCore/drivers/cpu/gdt/gdt.h
|
||||||
|
@echo -e "\e[1;35m[ 29%]\e[0m Global descriptor table"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-gdt.o SysCore/drivers/cpu/gdt/gdt.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-idt.o : SysCore/drivers/cpu/idt/idt.c SysCore/drivers/cpu/idt/idt.h \
|
||||||
|
SysCore/include/system.h
|
||||||
|
@echo -e "\e[1;35m[ 30%]\e[0m Interrupt descriptor table"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-idt.o SysCore/drivers/cpu/idt/idt.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-isrs.o : SysCore/drivers/cpu/isrs/isrs.c SysCore/drivers/cpu/isrs/isrs.h \
|
||||||
|
SysCore/drivers/cpu/idt/idt.h SysCore/include/system.h \
|
||||||
|
SysCore/include/conio.h
|
||||||
|
@echo -e "\e[1;35m[ 31%]\e[0m Interrupt service routines"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-isrs.o SysCore/drivers/cpu/isrs/isrs.c
|
||||||
|
|
||||||
|
|
||||||
|
$(OBJ)/driver-irq.o : SysCore/drivers/cpu/irq/irq.c SysCore/drivers/cpu/irq/irq.h \
|
||||||
|
SysCore/include/system.h SysCore/drivers/cpu/idt/idt.h \
|
||||||
|
SysCore/drivers/cpu/pic/pic.h
|
||||||
|
@echo -e "\e[1;35m[ 32%]\e[0m Interrupt requests"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-irq.o SysCore/drivers/cpu/irq/irq.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-pic.o : SysCore/drivers/cpu/irq/pic.c SysCore/drivers/cpu/irq/pic.h \
|
||||||
|
SysCore/include/system.h
|
||||||
|
@echo -e "\e[1;35m[ 33%]\e[0m Programmable interrupt controller"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-pic.o SysCore/drivers/cpu/irq/pic.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-pit.o : SysCore/drivers/clock/pit.c SysCore/drivers/clock/clock.h \
|
||||||
|
SysCore/include/system.h SysCore/include/time.h
|
||||||
|
@echo -e "\e[1;35m[ 34%]\e[0m Programmable interval timer"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-pit.o SysCore/drivers/clock/pic.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-keyboard.o : SysCore/drivers/keyboard/keyboard.c SysCore/include/system.h \
|
||||||
|
SysCore/include/drivers/keyboard.h
|
||||||
|
@echo -e "\e[1;35m[ 35%]\e[0m Keyboard"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-pic.o SysCore/drivers/cpu/irq/pic.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-dma.o : SysCore/drivers/floppy/dma.c SysCore/drivers/floppy/dma.h \
|
||||||
|
SysCore/include/system.h
|
||||||
|
@echo -e "\e[1;35m[ 36%]\e[0m DMA Controller"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-dma.o SysCore/drivers/floppy/dma.c
|
||||||
|
|
||||||
|
$(OBJ)/driver-floppy.o : SysCore/drivers/floppy/floppy.c SysCore/drivers/floppy/dma.h \
|
||||||
|
SysCore/include/system.h SysCore/include/time.h \
|
||||||
|
SysCore/include/conio.h SysCore/drivers/floppy/storage.h \
|
||||||
|
SysCore/drivers/floppy/floppy.h
|
||||||
|
@echo -e "\e[1;35m[ 37%]\e[0m FDC Controller"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-floppy.o SysCore/drivers/floppy/floppy.c
|
||||||
|
|
||||||
|
# TODO: add SysCore/drivers/filesys/vfs.h
|
||||||
|
$(OBJ)/driver-fat.o : SysCore/drivers/filesys/fat.c SysCore/drivers/filesys/fat.h \
|
||||||
|
SysCore/drivers/floppy/floppy.h SysCore/include/conio.h
|
||||||
|
@echo -e "\e[1;35m[ 38%]\e[0m File system"
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/driver-fat.o SysCore/drivers/floppy/fat.c
|
||||||
|
|
||||||
|
# TODO: add vfs.c
|
||||||
|
|
||||||
|
# TODO: add colors
|
||||||
|
$(OBJ)/video-vga03h.o : SysCore/video/vga03h.c SysCore/include/conio.h \
|
||||||
|
SysCore/include/system.h
|
||||||
|
@$(CC) $(CCPARAM) -o $(OBJ)/video-vga03h.o SysCore/video/vga03h.c
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY : clean
|
||||||
|
clean:
|
||||||
|
- rm ctaos.img
|
||||||
|
rm $(OBJ)*.*
|
||||||
Binary file not shown.
Binary file not shown.
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
bits 16
|
bits 16
|
||||||
|
|
||||||
%include "Floppy16.inc" ; the erm.. floppy driver
|
;%include "Floppy16.inc" ; the erm.. floppy driver
|
||||||
|
|
||||||
%define ROOT_OFFSET 0x2e00
|
%define ROOT_OFFSET 0x2e00
|
||||||
%define FAT_SEG 0x2c0
|
%define FAT_SEG 0x2c0
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ jmp main ; go to start
|
|||||||
%include "stdio.inc" ; basic i/o routines
|
%include "stdio.inc" ; basic i/o routines
|
||||||
%include "gdt.inc" ; Gdt routines
|
%include "gdt.inc" ; Gdt routines
|
||||||
%include "a20.inc" ; A20 enabling
|
%include "a20.inc" ; A20 enabling
|
||||||
|
%include "floppy16.inc"
|
||||||
%include "fat12.inc" ; FAT12 driver. Kinda :)
|
%include "fat12.inc" ; FAT12 driver. Kinda :)
|
||||||
%include "common.inc"
|
%include "common.inc"
|
||||||
;%include "bootinfo.inc"
|
;%include "bootinfo.inc"
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ set loader_name=loader
|
|||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
rem NASM and DJGPP executable paths:
|
||||||
set nasm_path=C:\nasm
|
set nasm_path=C:\nasm
|
||||||
set djgpp_path=C:\DJGPP\bin
|
set djgpp_path=C:\mingw\bin
|
||||||
|
|
||||||
rem Compile loader
|
rem Compile loader
|
||||||
@echo on
|
@echo on
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,195 @@
|
|||||||
|
00000000000i[ ] Bochs x86 Emulator 2.4.5
|
||||||
|
00000000000i[ ] Build from CVS snapshot, on April 25, 2010
|
||||||
|
00000000000i[ ] System configuration
|
||||||
|
00000000000i[ ] processors: 1 (cores=1, HT threads=1)
|
||||||
|
00000000000i[ ] A20 line support: yes
|
||||||
|
00000000000i[ ] CPU configuration
|
||||||
|
00000000000i[ ] level: 6
|
||||||
|
00000000000i[ ] SMP support: no
|
||||||
|
00000000000i[ ] APIC support: yes
|
||||||
|
00000000000i[ ] FPU support: yes
|
||||||
|
00000000000i[ ] MMX support: yes
|
||||||
|
00000000000i[ ] 3dnow! support: no
|
||||||
|
00000000000i[ ] SEP support: yes
|
||||||
|
00000000000i[ ] SSE support: sse2
|
||||||
|
00000000000i[ ] XSAVE support: no
|
||||||
|
00000000000i[ ] AES support: no
|
||||||
|
00000000000i[ ] MOVBE support: no
|
||||||
|
00000000000i[ ] x86-64 support: yes
|
||||||
|
00000000000i[ ] 1G paging support: no
|
||||||
|
00000000000i[ ] MWAIT support: no
|
||||||
|
00000000000i[ ] VMX support: no
|
||||||
|
00000000000i[ ] Optimization configuration
|
||||||
|
00000000000i[ ] RepeatSpeedups support: yes
|
||||||
|
00000000000i[ ] Trace cache support: yes
|
||||||
|
00000000000i[ ] Fast function calls: yes
|
||||||
|
00000000000i[ ] Devices configuration
|
||||||
|
00000000000i[ ] ACPI support: yes
|
||||||
|
00000000000i[ ] NE2000 support: yes
|
||||||
|
00000000000i[ ] PCI support: yes, enabled=yes
|
||||||
|
00000000000i[ ] SB16 support: yes
|
||||||
|
00000000000i[ ] USB support: yes
|
||||||
|
00000000000i[ ] VGA extension support: vbe cirrus
|
||||||
|
00000000000i[MEM0 ] allocated memory at 02720020. after alignment, vector=02721000
|
||||||
|
00000000000i[MEM0 ] 32.00MB
|
||||||
|
00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32
|
||||||
|
00000000000i[MEM0 ] rom at 0xe0000/131072 ('BIOS-bochs-latest')
|
||||||
|
00000000000i[MEM0 ] rom at 0xc0000/40448 ('VGABIOS-lgpl-latest')
|
||||||
|
00000000000i[CMOS ] Using local time for initial clock
|
||||||
|
00000000000i[CMOS ] Setting initial clock to: Sun Nov 07 17:10:07 2010 (time0=1289142607)
|
||||||
|
00000000000i[DMA ] channel 4 used by cascade
|
||||||
|
00000000000i[DMA ] channel 2 used by Floppy Drive
|
||||||
|
00000000000i[FDD ] fd0: 'ctaos.img' ro=0, h=2,t=80,spt=18
|
||||||
|
00000000000i[PCI ] 440FX Host bridge present at device 0, function 0
|
||||||
|
00000000000i[PCI ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
|
||||||
|
00000000000i[MEM0 ] Register memory access handlers: 0x000a0000 - 0x000bffff
|
||||||
|
00000000000i[WGUI ] Desktop Window dimensions: 1366 x 768
|
||||||
|
00000000000i[WGUI ] Number of Mouse Buttons = 5
|
||||||
|
00000000000i[WGUI ] IME disabled
|
||||||
|
00000000000i[MEM0 ] Register memory access handlers: 0xe0000000 - 0xe0ffffff
|
||||||
|
00000000000i[CLVGA] VBE Bochs Display Extension Enabled
|
||||||
|
00000000000i[CLVGA] interval=50000
|
||||||
|
00000000000i[ ] init_dev of 'unmapped' plugin device by virtual method
|
||||||
|
00000000000i[ ] init_dev of 'biosdev' plugin device by virtual method
|
||||||
|
00000000000i[ ] init_dev of 'speaker' plugin device by virtual method
|
||||||
|
00000000000i[ ] init_dev of 'extfpuirq' plugin device by virtual method
|
||||||
|
00000000000i[ ] init_dev of 'gameport' plugin device by virtual method
|
||||||
|
00000000000i[ ] init_dev of 'pci_ide' plugin device by virtual method
|
||||||
|
00000000000i[PCI ] PIIX3 PCI IDE controller present at device 1, function 1
|
||||||
|
00000000000i[ ] init_dev of 'acpi' plugin device by virtual method
|
||||||
|
00000000000i[PCI ] ACPI Controller present at device 1, function 3
|
||||||
|
00000000000i[ ] init_dev of 'ioapic' plugin device by virtual method
|
||||||
|
00000000000i[IOAP ] initializing I/O APIC
|
||||||
|
00000000000i[MEM0 ] Register memory access handlers: 0xfec00000 - 0xfec00fff
|
||||||
|
00000000000i[ ] init_dev of 'keyboard' plugin device by virtual method
|
||||||
|
00000000000i[KBD ] will paste characters every 1000 keyboard ticks
|
||||||
|
00000000000i[ ] init_dev of 'harddrv' plugin device by virtual method
|
||||||
|
00000000000i[HD ] Using boot sequence floppy, none, none
|
||||||
|
00000000000i[HD ] Floppy boot signature check is enabled
|
||||||
|
00000000000i[ ] init_dev of 'serial' plugin device by virtual method
|
||||||
|
00000000000i[SER ] com1 at 0x03f8 irq 4
|
||||||
|
00000000000i[ ] init_dev of 'parallel' plugin device by virtual method
|
||||||
|
00000000000i[PAR ] parallel port 1 at 0x0378 irq 7
|
||||||
|
00000000000i[ ] register state of 'unmapped' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'biosdev' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'speaker' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'extfpuirq' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'gameport' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'pci_ide' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'acpi' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'ioapic' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'keyboard' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'harddrv' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'serial' plugin device by virtual method
|
||||||
|
00000000000i[ ] register state of 'parallel' plugin device by virtual method
|
||||||
|
00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
|
||||||
|
00000000000i[CPU0 ] cpu hardware reset
|
||||||
|
00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0xfee00000
|
||||||
|
00000000000i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69
|
||||||
|
00000000000i[CPU0 ] CPUID[0x00000001]: 00000f20 00000800 00002000 078bfbff
|
||||||
|
00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
|
||||||
|
00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
|
||||||
|
00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
|
||||||
|
00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000
|
||||||
|
00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000101 2a100800
|
||||||
|
00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
|
||||||
|
00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
|
||||||
|
00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
|
||||||
|
00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
|
||||||
|
00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
|
||||||
|
00000000000i[CPU0 ] CPUID[0x80000008]: 00003020 00000000 00000000 00000000
|
||||||
|
00000000000i[ ] reset of 'unmapped' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'biosdev' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'speaker' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'extfpuirq' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'gameport' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'pci_ide' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'acpi' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'ioapic' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'keyboard' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'harddrv' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'serial' plugin device by virtual method
|
||||||
|
00000000000i[ ] reset of 'parallel' plugin device by virtual method
|
||||||
|
00000003305i[BIOS ] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $
|
||||||
|
00000200000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
|
||||||
|
00000318042i[KBD ] reset-disable command received
|
||||||
|
00000444800i[VBIOS] VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $
|
||||||
|
|
||||||
|
00000444871i[CLVGA] VBE known Display Interface b0c0
|
||||||
|
00000444903i[CLVGA] VBE known Display Interface b0c5
|
||||||
|
00000447828i[VBIOS] VBE Bios $Id: vbe.c,v 1.62 2009/01/25 15:46:25 vruppert Exp $
|
||||||
|
00000760517i[BIOS ] Starting rombios32
|
||||||
|
00000761014i[BIOS ] Shutdown flag 0
|
||||||
|
00000761695i[BIOS ] ram_size=0x02000000
|
||||||
|
00000762173i[BIOS ] ram_end=32MB
|
||||||
|
00000802745i[BIOS ] Found 1 cpu(s)
|
||||||
|
00000822014i[BIOS ] bios_table_addr: 0x000fbc18 end=0x000fcc00
|
||||||
|
00000822117i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
|
||||||
|
00001149814i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
|
||||||
|
00001477742i[P2I ] PCI IRQ routing: PIRQA# set to 0x0b
|
||||||
|
00001477763i[P2I ] PCI IRQ routing: PIRQB# set to 0x09
|
||||||
|
00001477784i[P2I ] PCI IRQ routing: PIRQC# set to 0x0b
|
||||||
|
00001477805i[P2I ] PCI IRQ routing: PIRQD# set to 0x09
|
||||||
|
00001477815i[P2I ] write: ELCR2 = 0x0a
|
||||||
|
00001478700i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a
|
||||||
|
00001486658i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600
|
||||||
|
00001489220i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601
|
||||||
|
00001491621i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101
|
||||||
|
00001491851i[PIDE ] new BM-DMA address: 0xc000
|
||||||
|
00001492555i[BIOS ] region 4: 0x0000c000
|
||||||
|
00001494865i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680
|
||||||
|
00001495103i[ACPI ] new irq line = 11
|
||||||
|
00001495117i[ACPI ] new irq line = 9
|
||||||
|
00001495147i[ACPI ] new PM base address: 0xb000
|
||||||
|
00001495161i[ACPI ] new SM base address: 0xb100
|
||||||
|
00001495189i[PCI ] setting SMRAM control register to 0x4a
|
||||||
|
00001659283i[CPU0 ] Enter to System Management Mode
|
||||||
|
00001659293i[CPU0 ] RSM: Resuming from System Management Mode
|
||||||
|
00001823313i[PCI ] setting SMRAM control register to 0x0a
|
||||||
|
00001832484i[BIOS ] MP table addr=0x000fbcf0 MPC table addr=0x000fbc20 size=0xd0
|
||||||
|
00001834543i[BIOS ] SMBIOS table addr=0x000fbd00
|
||||||
|
00001836931i[BIOS ] ACPI tables: RSDP addr=0x000fbe20 ACPI DATA addr=0x01ff0000 size=0x988
|
||||||
|
00001840169i[BIOS ] Firmware waking vector 0x1ff00cc
|
||||||
|
00001851282i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
|
||||||
|
00001852126i[BIOS ] bios_table_cur_addr: 0x000fbe44
|
||||||
|
00014041543i[BIOS ] Booting from 0000:7c00
|
||||||
|
00026325033i[KBD ] setting typematic info
|
||||||
|
00026325046i[KBD ] setting delay to 500 mS (unused)
|
||||||
|
00026325046i[KBD ] setting repeat rate to 10.9 cps (unused)
|
||||||
|
00026325079i[KBD ] Switched to scancode set 2
|
||||||
|
00026325154i[KBD ] keyboard: scan convert turned off
|
||||||
|
00026326238i[FDD ] controller reset in software
|
||||||
|
00026326585i[FDD ] io_write: config control register: 0x00
|
||||||
|
00026326642e[FDD ] non DMA mode not fully implemented yet
|
||||||
|
00055764602e[FDD ] non DMA mode not fully implemented yet
|
||||||
|
00055764757e[FDD ] non DMA mode not fully implemented yet
|
||||||
|
00067767563p[FDD ] >>PANIC<< write 0x03f5: receiving new command 0x03, old one (0xc6) pending
|
||||||
|
00067767563i[CPU0 ] CPU is in protected mode (active)
|
||||||
|
00067767563i[CPU0 ] CS.d_b = 32 bit
|
||||||
|
00067767563i[CPU0 ] SS.d_b = 32 bit
|
||||||
|
00067767563i[CPU0 ] EFER = 0x00000000
|
||||||
|
00067767563i[CPU0 ] | RAX=0000000000000003 RBX=0000000000000000
|
||||||
|
00067767563i[CPU0 ] | RCX=0000000000000012 RDX=00000000000003f5
|
||||||
|
00067767563i[CPU0 ] | RSP=000000000008fd68 RBP=00000000c000a21c
|
||||||
|
00067767563i[CPU0 ] | RSI=0000000000000000 RDI=0000000000000001
|
||||||
|
00067767563i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
|
||||||
|
00067767563i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
|
||||||
|
00067767563i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
|
||||||
|
00067767563i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
|
||||||
|
00067767563i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df IF tf SF zf af pf cf
|
||||||
|
00067767563i[CPU0 ] | SEG selector base limit G D
|
||||||
|
00067767563i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
|
||||||
|
00067767563i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
|
||||||
|
00067767563i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
|
00067767563i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
|
00067767563i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
|
00067767563i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
|
00067767563i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
|
||||||
|
00067767563i[CPU0 ] | MSR_FS_BASE:0000000000000000
|
||||||
|
00067767563i[CPU0 ] | MSR_GS_BASE:0000000000000000
|
||||||
|
00067767563i[CPU0 ] | RIP=00000000c00040be (00000000c00040bd)
|
||||||
|
00067767563i[CPU0 ] | CR0=0xe0000011 CR2=0x0000000000000000
|
||||||
|
00067767563i[CPU0 ] | CR3=0x00001000 CR4=0x00000000
|
||||||
|
00067767563i[CPU0 ] 0x00000000c00040bd>> out dx, al : EE
|
||||||
|
00067767563i[CMOS ] Last time is 1289142623 (Sun Nov 07 17:10:23 2010)
|
||||||
|
00067767563i[ ] restoring default signal behavior
|
||||||
Binary file not shown.
@@ -0,0 +1,17 @@
|
|||||||
|
# ROM and VGA BIOS images ---------------------------------------------
|
||||||
|
|
||||||
|
romimage: file=BIOS-bochs-latest, address=0xe0000
|
||||||
|
vgaromimage: file=VGABIOS-lgpl-latest
|
||||||
|
|
||||||
|
# boot from floppy using our disk image -------------------------------
|
||||||
|
|
||||||
|
floppya: 1_44=ctaos.img, status=inserted
|
||||||
|
|
||||||
|
# logging and reporting -----------------------------------------------
|
||||||
|
|
||||||
|
log: OSDev.log # All errors and info logs will output to OSDev.log
|
||||||
|
error: action=report
|
||||||
|
info: action=report
|
||||||
|
|
||||||
|
magic_break: enabled=1
|
||||||
|
|
||||||
Binary file not shown.
@@ -81,4 +81,5 @@ char *exception_messages[] = {
|
|||||||
void _STOP_ERROR_SCREEN (ISR_stack_regs *r)
|
void _STOP_ERROR_SCREEN (ISR_stack_regs *r)
|
||||||
{
|
{
|
||||||
cprintf ("%#0C** Fatal Error: "); cprintf("%#0E %s \n\r", exception_messages[r->int_no]);
|
cprintf ("%#0C** Fatal Error: "); cprintf("%#0E %s \n\r", exception_messages[r->int_no]);
|
||||||
|
for (;;);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef __PIT_H
|
||||||
|
#define __PIT_H
|
||||||
|
|
||||||
|
#include <regs.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
extern void i86_PitHandler(ISR_stack_regs *r);
|
||||||
|
extern void i86_PitInitialize(int freq);
|
||||||
|
extern unsigned char PitIsInitialized();
|
||||||
|
extern void PitSetFrequency(int frequency);
|
||||||
|
extern unsigned int PitGetFrequency();
|
||||||
|
|
||||||
|
extern TIME ClockGetTime();
|
||||||
|
extern unsigned int ClockSetTickCount(unsigned int i);
|
||||||
|
extern unsigned int ClockGetTickCount();
|
||||||
|
|
||||||
|
extern void i86_SetRTC (const TIME* time);
|
||||||
|
extern void i86_GetRTC(TIME* tim);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
#include <system.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "clock.h"
|
||||||
|
|
||||||
|
volatile unsigned int ClockTicks = 0;
|
||||||
|
volatile unsigned int ClockFrequency = 0;
|
||||||
|
unsigned char PitInitialized = 0;
|
||||||
|
volatile TIME _InternalClock;
|
||||||
|
|
||||||
|
|
||||||
|
void PitSetFrequency(int frequency)
|
||||||
|
{
|
||||||
|
int divisor = 1193180/frequency; // Calculate the divisor
|
||||||
|
outportb(0x43, 0x36); // Set our command byte 0x36
|
||||||
|
outportb(0x40, divisor&0xFF); // Set low byte
|
||||||
|
outportb(0x40, divisor>>8); // Set high byte
|
||||||
|
ClockFrequency = frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
void i86_PitHandler(ISR_stack_regs *r)
|
||||||
|
{
|
||||||
|
ClockTicks++; // count tick
|
||||||
|
if (ClockTicks % ClockFrequency == 0)
|
||||||
|
_CLOCK_INC((TIME*)&_InternalClock); // update internal clock
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ClockSetTickCount(unsigned int i)
|
||||||
|
{
|
||||||
|
unsigned int r = ClockTicks;
|
||||||
|
ClockTicks = i;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ClockGetTickCount()
|
||||||
|
{
|
||||||
|
return ClockTicks;
|
||||||
|
}
|
||||||
|
unsigned int PitGetFrequency()
|
||||||
|
{
|
||||||
|
return ClockFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
void i86_PitInitialize(int freq)
|
||||||
|
{
|
||||||
|
PitSetFrequency(freq);
|
||||||
|
ClockTicks = 0;
|
||||||
|
|
||||||
|
i86_GetRTC((TIME*) &_InternalClock);
|
||||||
|
|
||||||
|
PitInitialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIME ClockGetTime()
|
||||||
|
{
|
||||||
|
return _InternalClock;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char PitIsInitialized()
|
||||||
|
{
|
||||||
|
return PitInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline unsigned char CmosRead (unsigned char address)
|
||||||
|
{
|
||||||
|
outportb(0x70, address); iowait();
|
||||||
|
return inportb(0x71);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CmosWrite (unsigned char address, unsigned char val)
|
||||||
|
{
|
||||||
|
outportb(0x70, address); iowait();
|
||||||
|
outportb(0x71, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void i86_SetRTC (const TIME* time)
|
||||||
|
{
|
||||||
|
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
|
||||||
|
unsigned char ampm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
|
||||||
|
|
||||||
|
CmosWrite (0, (BCD) ? (time->second%10) | (time->second/10*16) : time->second); // Seconds
|
||||||
|
CmosWrite (2, (BCD) ? (time->minute%10) | (time->minute/10*16) : time->minute); // Minutes
|
||||||
|
|
||||||
|
if (ampm && time->hour > 12) // Hours
|
||||||
|
CmosWrite (4, (BCD) ? (((time->hour - 12) % 10) | ((time->hour - 12)/10*16) | 0x80) : (time->hour | 0x80) );
|
||||||
|
|
||||||
|
else if (ampm && time->hour == 0) // Midnight convention: 12 PM = 00:00
|
||||||
|
CmosWrite (4, (BCD) ? 0x92 : 0x8C);
|
||||||
|
|
||||||
|
else CmosWrite (4, (BCD) ? (time->hour%10) | (time->hour/10*16) : time->hour); // 24h / AM
|
||||||
|
|
||||||
|
CmosWrite (6, (BCD) ? (time->weekday%10) | (time->weekday/10*16) : time->weekday); // Weekday
|
||||||
|
CmosWrite (7, (BCD) ? (time->day%10) | (time->day/10*16) : time->day); // Day
|
||||||
|
CmosWrite (8, (BCD) ? (time->month%10) | (time->month/10*16) : time->month); // Month
|
||||||
|
CmosWrite (9, (BCD) ? (time->year%10) | (time->year/10*16) : time->year); // Year
|
||||||
|
CmosWrite (0x32, (BCD) ? (time->century%10) | (time->century/10*16) : time->century); // Century
|
||||||
|
}
|
||||||
|
|
||||||
|
void i86_GetRTC(TIME* tim)
|
||||||
|
{
|
||||||
|
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
|
||||||
|
unsigned char am_pm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
|
||||||
|
|
||||||
|
tim->second = (BCD) ? (CmosRead(0x00)%16) + 10*(CmosRead(0x00)/16): CmosRead(0x00);
|
||||||
|
tim->minute = (BCD) ? (CmosRead(0x02)%16) + 10*(CmosRead(0x02)/16): CmosRead(0x02);
|
||||||
|
|
||||||
|
// Time is PM
|
||||||
|
if (am_pm && CmosRead(0x04)&80) {
|
||||||
|
tim->hour = (BCD) ? ((CmosRead(0x04)-0x80)%16) + 10*((CmosRead(0x04)-0x80)/16): CmosRead(0x04)-0x80;
|
||||||
|
tim->hour += 12;
|
||||||
|
}
|
||||||
|
// 24Hour format, or AM
|
||||||
|
else tim->hour = (BCD) ? (CmosRead(0x04)%16) + 10*(CmosRead(0x04)/16): CmosRead(0x04);
|
||||||
|
|
||||||
|
tim->weekday = (BCD) ? (CmosRead(0x06)%16) + 10*(CmosRead(0x06)/16): CmosRead(0x06);
|
||||||
|
tim->day = (BCD) ? (CmosRead(0x07)%16) + 10*(CmosRead(0x07)/16): CmosRead(0x07);
|
||||||
|
tim->month = (BCD) ? (CmosRead(0x08)%16) + 10*(CmosRead(0x08)/16): CmosRead(0x08);
|
||||||
|
tim->year = (BCD) ? (CmosRead(0x09)%16) + 10*(CmosRead(0x09)/16): CmosRead(0x09);
|
||||||
|
tim->century = (BCD) ? (CmosRead(0x32)%16) + 10*(CmosRead(0x32)/16): CmosRead(0x32);
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
set loader_name=loader
|
set loader_name=loader
|
||||||
set nasm_path=C:\nasm
|
set nasm_path=C:\nasm
|
||||||
set djgpp_path=C:\DJGPP\bin
|
set djgpp_path=C:\mingw\bin
|
||||||
|
|
||||||
|
|
||||||
@echo ***************** CTA KERNEL *****************
|
@echo ***************** CTA KERNEL *****************
|
||||||
@@ -4,7 +4,7 @@ set loader_name=loader
|
|||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
rem NASM and DJGPP executable paths:
|
||||||
set nasm_path=C:\nasm
|
set nasm_path=C:\nasm
|
||||||
set djgpp_path=C:\DJGPP\bin
|
set djgpp_path=C:\mingw\bin
|
||||||
set objpath=../../objects
|
set objpath=../../objects
|
||||||
set incpath=../../include
|
set incpath=../../include
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#include <system.h>
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "gdt/gdt.h"
|
||||||
|
#include "idt/idt.h"
|
||||||
|
#include "irq/irq.h"
|
||||||
|
#include "isrs/isrs.h"
|
||||||
|
|
||||||
|
#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
|
||||||
|
|
||||||
|
// initializes cpu resources
|
||||||
|
void i86_CpuInitialize()
|
||||||
|
{
|
||||||
|
i86_GdtInstall();
|
||||||
|
i86_IdtInstall();
|
||||||
|
i86_IsrsInstall();
|
||||||
|
i86_IrqInstall();
|
||||||
|
}
|
||||||
|
|
||||||
|
void i86_CpuShutdown()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char* i86_CpuGetVendor()
|
||||||
|
{
|
||||||
|
unsigned unused;
|
||||||
|
unsigned static arr[3];
|
||||||
|
|
||||||
|
cpuid(0, unused, arr[0], arr[2], arr[1]);
|
||||||
|
|
||||||
|
return (char*) arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
_R32BIT i86_CpuID(unsigned function)
|
||||||
|
{
|
||||||
|
_R32BIT ret = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
cpuid(function, ret.eax, ret.ebx, ret.ecx, ret.edx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _CPU_H_INCLUDED
|
||||||
|
#define _CPU_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <regs.h>
|
||||||
|
#include "gdt/gdt.h"
|
||||||
|
#include "idt/idt.h"
|
||||||
|
#include "irq/irq.h"
|
||||||
|
#include "irq/pic.h"
|
||||||
|
#include "isrs/isrs.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern void i86_CpuInitialize ();
|
||||||
|
extern void i86_CpuShutdown ();
|
||||||
|
extern char* i86_CpuGetVendor ();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,9 +5,9 @@ bits 32
|
|||||||
; far jump. A jump that includes a segment as well as an offset.
|
; far jump. A jump that includes a segment as well as an offset.
|
||||||
; This is declared in C as 'extern void gdt_flush();'
|
; This is declared in C as 'extern void gdt_flush();'
|
||||||
|
|
||||||
global _i86_gdt_flush ; Allows the C code to link to this
|
global _i86_GdtFlush ; Allows the C code to link to this
|
||||||
extern _gp ; Says that '_gp' is in another file
|
extern _gp ; Says that '_gp' is in another file
|
||||||
_i86_gdt_flush:
|
_i86_GdtFlush:
|
||||||
lgdt [_gp] ; Load the GDT with our '_gp' which is a special pointer
|
lgdt [_gp] ; Load the GDT with our '_gp' which is a special pointer
|
||||||
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
@@ -5,14 +5,19 @@
|
|||||||
#define MAX_DESCRIPTORS 5
|
#define MAX_DESCRIPTORS 5
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
|
|
||||||
|
extern void i86_GdtInstall();
|
||||||
|
|
||||||
/* Our GDT, with 3 entries, and finally our special GDT pointer */
|
/* Our GDT, with 3 entries, and finally our special GDT pointer */
|
||||||
struct gdt_entry gdt[3];
|
struct GdtEntry gdt[MAX_DESCRIPTORS];
|
||||||
struct gdt_ptr gp;
|
struct GdtPointer gp;
|
||||||
|
|
||||||
|
|
||||||
/* Setup a descriptor in the Global Descriptor Table */
|
/* Setup a descriptor in the Global Descriptor Table */
|
||||||
void i86_gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
|
void i86_GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
|
||||||
{
|
{
|
||||||
|
/* Sanity check */
|
||||||
|
if (num >= MAX_DESCRIPTORS) return;
|
||||||
|
|
||||||
/* Setup the descriptor base address */
|
/* Setup the descriptor base address */
|
||||||
gdt[num].base_low = (base & 0xFFFF);
|
gdt[num].base_low = (base & 0xFFFF);
|
||||||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
gdt[num].base_middle = (base >> 16) & 0xFF;
|
||||||
@@ -27,45 +32,45 @@ void i86_gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned
|
|||||||
gdt[num].access = access;
|
gdt[num].access = access;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gdt_entry* i86_gdt_get_gate(int num)
|
/*struct gdt_entry* i86_GdtGetGate(int num)
|
||||||
{
|
{
|
||||||
if (num>MAX_DESCRIPTORS) return 0;
|
if (num>MAX_DESCRIPTORS) return 0;
|
||||||
return &gdt[num];
|
return &gdt[num];
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/* Should be called by main. This will setup the special GDT
|
/* Should be called by main. This will setup the special GDT
|
||||||
* pointer, set up the first 3 entries in our GDT, and then
|
* pointer, set up the first 3 entries in our GDT, and then
|
||||||
* finally call gdt_flush() in our assembler file in order
|
* finally call gdt_flush() in our assembler file in order
|
||||||
* to tell the processor where the new GDT is and update the
|
* to tell the processor where the new GDT is and update the
|
||||||
* new segment registers */
|
* new segment registers */
|
||||||
void i86_gdt_install()
|
void i86_GdtInstall()
|
||||||
{
|
{
|
||||||
/* Setup the GDT pointer and limit */
|
/* Setup the GDT pointer and limit */
|
||||||
gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
|
gp.limit = (sizeof(struct GdtEntry) * 3) - 1;
|
||||||
gp.base = (unsigned int)&gdt;
|
gp.base = (unsigned int)&gdt;
|
||||||
|
|
||||||
/* Our NULL descriptor */
|
/* Our NULL descriptor */
|
||||||
i86_gdt_set_gate(0, 0, 0, 0, 0);
|
i86_GdtSetGate(0, 0, 0, 0, 0);
|
||||||
|
|
||||||
/* The second entry is our Code Segment. The base address
|
/* The second entry is our Code Segment. The base address
|
||||||
* is 0, the limit is 4GBytes, it uses 4KByte granularity,
|
* is 0, the limit is 4GBytes, it uses 4KByte granularity,
|
||||||
* uses 32-bit opcodes, and is a Code Segment descriptor.
|
* uses 32-bit opcodes, and is a Code Segment descriptor.
|
||||||
* Please check the table above in the tutorial in order
|
* Please check the table above in the tutorial in order
|
||||||
* to see exactly what each value means */
|
* to see exactly what each value means */
|
||||||
i86_gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
i86_GdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||||
|
|
||||||
/* The third entry is our Data Segment. It's EXACTLY the
|
/* The third entry is our Data Segment. It's EXACTLY the
|
||||||
* same as our code segment, but the descriptor type in
|
* same as our code segment, but the descriptor type in
|
||||||
* this entry's access byte says it's a Data Segment */
|
* this entry's access byte says it's a Data Segment */
|
||||||
i86_gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
i86_GdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||||
|
|
||||||
/* User mode Code segment*/
|
/* User mode Code segment*/
|
||||||
i86_gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
i86_GdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||||
|
|
||||||
/* User mode data segment*/
|
/* User mode data segment*/
|
||||||
i86_gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
i86_GdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||||
|
|
||||||
/* Flush out the old GDT and install the new changes! */
|
/* Flush out the old GDT and install the new changes! */
|
||||||
i86_gdt_flush();
|
i86_GdtFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
/* Defines a GDT entry. We say packed, because it prevents the
|
/* Defines a GDT entry. We say packed, because it prevents the
|
||||||
* compiler from doing things that it thinks is best: Prevent
|
* compiler from doing things that it thinks is best: Prevent
|
||||||
* compiler "optimization" by packing */
|
* compiler "optimization" by packing */
|
||||||
struct gdt_entry
|
struct GdtEntry
|
||||||
{
|
{
|
||||||
unsigned short limit_low;
|
unsigned short limit_low;
|
||||||
unsigned short base_low;
|
unsigned short base_low;
|
||||||
@@ -21,7 +21,7 @@ struct gdt_entry
|
|||||||
|
|
||||||
/* Special pointer which includes the limit: The max bytes
|
/* Special pointer which includes the limit: The max bytes
|
||||||
* taken up by the GDT, minus 1. Again, this NEEDS to be packed */
|
* taken up by the GDT, minus 1. Again, this NEEDS to be packed */
|
||||||
struct gdt_ptr
|
struct GdtPointer
|
||||||
{
|
{
|
||||||
unsigned short limit;
|
unsigned short limit;
|
||||||
unsigned int base;
|
unsigned int base;
|
||||||
@@ -30,10 +30,9 @@ struct gdt_ptr
|
|||||||
|
|
||||||
/* This will be a function in start.asm. We use this to properly
|
/* This will be a function in start.asm. We use this to properly
|
||||||
* reload the new segment registers */
|
* reload the new segment registers */
|
||||||
extern void i86_gdt_flush();
|
extern void i86_GdtInstall();
|
||||||
extern void i86_gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
extern void i86_GdtFlush();
|
||||||
extern struct gdt_entry* i86_gdt_get_gate(int num);
|
extern void i86_GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
||||||
|
//extern struct GdtEntry* i86_GdtGetGate(int num);
|
||||||
extern void i86_gdt_install();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,8 +2,8 @@ bits 32
|
|||||||
|
|
||||||
; !!! IDT !!!
|
; !!! IDT !!!
|
||||||
; Loads the IDT defined in '_idtp'
|
; Loads the IDT defined in '_idtp'
|
||||||
global _i86_idt_load
|
global _i86_IdtLoad
|
||||||
extern _idtp
|
extern _idtp
|
||||||
_i86_idt_load:
|
_i86_IdtLoad:
|
||||||
lidt [_idtp]
|
lidt [_idtp]
|
||||||
ret
|
ret
|
||||||
@@ -5,18 +5,14 @@
|
|||||||
#include <system.h>
|
#include <system.h>
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
|
|
||||||
/* Declare an IDT of 256 entries. Although we will only use the
|
extern void i86_IdtLoad();
|
||||||
* first 32 entries in this tutorial, the rest exists as a bit
|
/* Declare an IDT of 256 entries. */
|
||||||
* of a trap. If any undefined IDT entry is hit, it normally
|
struct IdtEntry idt[256];
|
||||||
* will cause an "Unhandled Interrupt" exception. Any descriptor
|
struct IdtPointer idtp;
|
||||||
* for which the 'presence' bit is cleared (0) will generate an
|
|
||||||
* "Unhandled Interrupt" exception */
|
|
||||||
struct idt_entry idt[256];
|
|
||||||
struct idt_ptr idtp;
|
|
||||||
|
|
||||||
/* Use this function to set an entry in the IDT. Alot simpler
|
/* Use this function to set an entry in the IDT. Alot simpler
|
||||||
* than twiddling with the GDT ;) */
|
* than twiddling with the GDT ;) */
|
||||||
void i86_idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
|
void i86_IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
|
||||||
{
|
{
|
||||||
/* The interrupt routine's base address */
|
/* The interrupt routine's base address */
|
||||||
idt[num].base_lo = (base & 0xFFFF);
|
idt[num].base_lo = (base & 0xFFFF);
|
||||||
@@ -29,21 +25,21 @@ void i86_idt_set_gate(unsigned char num, unsigned long base, unsigned short sel,
|
|||||||
idt[num].flags = flags;
|
idt[num].flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct idt_entry* i86_idt_get_gate(unsigned char num)
|
struct IdtEntry* i86_IdtGetGate(unsigned char num)
|
||||||
{
|
{
|
||||||
return &idt[num];
|
return &idt[num];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Installs the IDT */
|
/* Installs the IDT */
|
||||||
void i86_idt_install()
|
void i86_IdtInstall()
|
||||||
{
|
{
|
||||||
/* Sets the special IDT pointer up, just like in 'gdt.c' */
|
/* Sets the special IDT pointer up, just like in 'gdt.c' */
|
||||||
idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
|
idtp.limit = (sizeof (struct IdtEntry) * 256) - 1;
|
||||||
idtp.base = (unsigned int)&idt;
|
idtp.base = (unsigned int)&idt;
|
||||||
|
|
||||||
/* Clear out the entire IDT, initializing it to zeros */
|
/* Clear out the entire IDT, initializing it to zeros */
|
||||||
memset (&idt, 0, sizeof(struct idt_entry) * 256);
|
memset (&idt, 0, sizeof(struct IdtEntry) * 256);
|
||||||
|
|
||||||
/* Points the processor's internal register to the new IDT */
|
/* Points the processor's internal register to the new IDT */
|
||||||
i86_idt_load();
|
i86_IdtLoad();
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#define __IDT_H
|
#define __IDT_H
|
||||||
|
|
||||||
/* Defines an IDT entry */
|
/* Defines an IDT entry */
|
||||||
struct idt_entry
|
struct IdtEntry
|
||||||
{
|
{
|
||||||
unsigned short base_lo;
|
unsigned short base_lo;
|
||||||
unsigned short sel;
|
unsigned short sel;
|
||||||
@@ -16,7 +16,7 @@ struct idt_entry
|
|||||||
unsigned short base_hi;
|
unsigned short base_hi;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct idt_ptr
|
struct IdtPointer
|
||||||
{
|
{
|
||||||
unsigned short limit;
|
unsigned short limit;
|
||||||
unsigned int base;
|
unsigned int base;
|
||||||
@@ -24,9 +24,8 @@ struct idt_ptr
|
|||||||
|
|
||||||
|
|
||||||
/* This exists in 'start.asm', and is used to load our IDT */
|
/* This exists in 'start.asm', and is used to load our IDT */
|
||||||
extern void i86_idt_load();
|
extern void i86_IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
||||||
extern void i86_idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
extern struct IdtEntry* i86_IdtGetGate(unsigned char num);
|
||||||
extern struct idt_entry* i86_idt_get_gate(unsigned char num);
|
extern void i86_IdtInstall();
|
||||||
extern void i86_idt_install();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -130,7 +130,7 @@ _i86_irq15:
|
|||||||
push byte 47
|
push byte 47
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
extern _i86_irq_handler
|
extern _i86_IrqHandler
|
||||||
|
|
||||||
; This is a stub that we have created for IRQ based ISRs. This calls
|
; This is a stub that we have created for IRQ based ISRs. This calls
|
||||||
; '_i86_irq_handler' in our C code. We need to create this in an 'irq.c'
|
; '_i86_irq_handler' in our C code. We need to create this in an 'irq.c'
|
||||||
@@ -147,7 +147,7 @@ irq_common_stub:
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov eax, esp
|
mov eax, esp
|
||||||
push eax
|
push eax
|
||||||
mov eax, _i86_irq_handler
|
mov eax, _i86_IrqHandler
|
||||||
call eax
|
call eax
|
||||||
pop eax
|
pop eax
|
||||||
pop gs
|
pop gs
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
#include <system.h>
|
||||||
|
#include "pic.h"
|
||||||
|
#include "irq.h"
|
||||||
|
#include "../idt/idt.h"
|
||||||
|
|
||||||
|
/* These are own ISRs that point to our special IRQ handler
|
||||||
|
* instead of the regular 'fault_handler' function */
|
||||||
|
extern void i86_irq0();
|
||||||
|
extern void i86_irq1();
|
||||||
|
extern void i86_irq2();
|
||||||
|
extern void i86_irq3();
|
||||||
|
extern void i86_irq4();
|
||||||
|
extern void i86_irq5();
|
||||||
|
extern void i86_irq6();
|
||||||
|
extern void i86_irq7();
|
||||||
|
extern void i86_irq8();
|
||||||
|
extern void i86_irq9();
|
||||||
|
extern void i86_irq10();
|
||||||
|
extern void i86_irq11();
|
||||||
|
extern void i86_irq12();
|
||||||
|
extern void i86_irq13();
|
||||||
|
extern void i86_irq14();
|
||||||
|
extern void i86_irq15();
|
||||||
|
|
||||||
|
/* This array is actually an array of function pointers. We use
|
||||||
|
* this to handle custom IRQ handlers for a given IRQ */
|
||||||
|
void *IrqRoutines[16] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This installs a custom IRQ handler for the given IRQ */
|
||||||
|
void i86_IrqInstallHandler (int irq, void (*handler)(ISR_stack_regs *r))
|
||||||
|
{
|
||||||
|
IrqRoutines[irq] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void i86_IrqUninstallHandler (int irq)
|
||||||
|
{
|
||||||
|
IrqRoutines[irq] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* We first remap the interrupt controllers, and then we install
|
||||||
|
* the appropriate ISRs to the correct entries in the IDT. This
|
||||||
|
* is just like installing the exception handlers */
|
||||||
|
void i86_IrqInstall()
|
||||||
|
{
|
||||||
|
i86_PicRemap(32,40);
|
||||||
|
|
||||||
|
i86_IdtSetGate(32, (unsigned)i86_irq0, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(33, (unsigned)i86_irq1, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(34, (unsigned)i86_irq2, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(35, (unsigned)i86_irq3, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(36, (unsigned)i86_irq4, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(37, (unsigned)i86_irq5, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(38, (unsigned)i86_irq6, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(39, (unsigned)i86_irq7, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(40, (unsigned)i86_irq8, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(41, (unsigned)i86_irq9, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(42, (unsigned)i86_irq10, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(43, (unsigned)i86_irq11, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(44, (unsigned)i86_irq12, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(45, (unsigned)i86_irq13, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(46, (unsigned)i86_irq14, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(47, (unsigned)i86_irq15, 0x08, 0x8E);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Each of the IRQ ISRs point to this function, rather than
|
||||||
|
* the 'fault_handler' in 'isrs.c'. The IRQ Controllers need
|
||||||
|
* to be told when you are done servicing them, so you need
|
||||||
|
* to send them an "End of Interrupt" command (0x20). There
|
||||||
|
* are two 8259 chips: The first exists at 0x20, the second
|
||||||
|
* exists at 0xA0. If the second controller (an IRQ from 8 to
|
||||||
|
* 15) gets an interrupt, you need to acknowledge the
|
||||||
|
* interrupt at BOTH controllers, otherwise, you only send
|
||||||
|
* an EOI command to the first controller. If you don't send
|
||||||
|
* an EOI, you won't raise any more IRQs */
|
||||||
|
void i86_IrqHandler (ISR_stack_regs *r)
|
||||||
|
{
|
||||||
|
/* This is a blank function pointer */
|
||||||
|
void (*handler)(ISR_stack_regs *r);
|
||||||
|
|
||||||
|
/* Find out if we have a custom handler to run for this
|
||||||
|
* IRQ, and then finally, run it */
|
||||||
|
handler = IrqRoutines[r->int_no - 32];
|
||||||
|
if (handler) handler(r);
|
||||||
|
|
||||||
|
/* If the IDT entry that was invoked was greater than 40
|
||||||
|
* (meaning IRQ8 - 15), then we need to send an EOI to
|
||||||
|
* the slave controller */
|
||||||
|
if (r->int_no >=40) outportb(0x0A, 0x20);
|
||||||
|
|
||||||
|
/* In either case, we need to send an EOI to the master
|
||||||
|
* interrupt controller too */
|
||||||
|
outportb(0x20, 0x20);
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __IRQ_H
|
||||||
|
#define __IRQ_H
|
||||||
|
|
||||||
|
#include <regs.h>
|
||||||
|
|
||||||
|
extern void i86_IrqInstallHandler (int irq, void (*handler)(ISR_stack_regs *r));
|
||||||
|
extern void i86_IrqUninstallHandler (int irq);
|
||||||
|
extern void i86_IrqInstall();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <system.h>
|
#include <system.h>
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
|
|
||||||
void i86_pic_remap(int pic1, int pic2)
|
void i86_PicRemap(int pic1, int pic2)
|
||||||
{
|
{
|
||||||
// Send ICW1
|
// Send ICW1
|
||||||
outportb(0x20, 0x11);
|
outportb(0x20, 0x11);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _PIC_H
|
||||||
|
#define _PIC_H
|
||||||
|
|
||||||
|
extern void i86_PicRemap(int pic1, int pic2);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -190,7 +190,7 @@ _i86_isr31:
|
|||||||
push byte 31
|
push byte 31
|
||||||
jmp isr_common_stub
|
jmp isr_common_stub
|
||||||
|
|
||||||
extern _i86_fault_handler
|
extern _i86_FaultHandler
|
||||||
|
|
||||||
isr_common_stub:
|
isr_common_stub:
|
||||||
pusha
|
pusha
|
||||||
@@ -205,7 +205,7 @@ isr_common_stub:
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov eax, esp ; Push us the stack
|
mov eax, esp ; Push us the stack
|
||||||
push eax
|
push eax
|
||||||
mov eax, _i86_fault_handler
|
mov eax, _i86_FaultHandler
|
||||||
call eax ; A special call, preserves the 'eip' register
|
call eax ; A special call, preserves the 'eip' register
|
||||||
pop eax
|
pop eax
|
||||||
pop gs
|
pop gs
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
#include <system.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include "isrs.h"
|
||||||
|
#include "../idt/idt.h"
|
||||||
|
|
||||||
|
// Assembly coded
|
||||||
|
extern void i86_isr0();
|
||||||
|
extern void i86_isr1();
|
||||||
|
extern void i86_isr2();
|
||||||
|
extern void i86_isr3();
|
||||||
|
extern void i86_isr4();
|
||||||
|
extern void i86_isr5();
|
||||||
|
extern void i86_isr6();
|
||||||
|
extern void i86_isr7();
|
||||||
|
extern void i86_isr8();
|
||||||
|
extern void i86_isr9();
|
||||||
|
extern void i86_isr10();
|
||||||
|
extern void i86_isr11();
|
||||||
|
extern void i86_isr12();
|
||||||
|
extern void i86_isr13();
|
||||||
|
extern void i86_isr14();
|
||||||
|
extern void i86_isr15();
|
||||||
|
extern void i86_isr16();
|
||||||
|
extern void i86_isr17();
|
||||||
|
extern void i86_isr18();
|
||||||
|
extern void i86_isr19();
|
||||||
|
extern void i86_isr20();
|
||||||
|
extern void i86_isr21();
|
||||||
|
extern void i86_isr22();
|
||||||
|
extern void i86_isr23();
|
||||||
|
extern void i86_isr24();
|
||||||
|
extern void i86_isr25();
|
||||||
|
extern void i86_isr26();
|
||||||
|
extern void i86_isr27();
|
||||||
|
extern void i86_isr28();
|
||||||
|
extern void i86_isr29();
|
||||||
|
extern void i86_isr30();
|
||||||
|
extern void i86_isr31();
|
||||||
|
|
||||||
|
|
||||||
|
void* IdtFaultHandlers[32] = {
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
};
|
||||||
|
|
||||||
|
void i86_IsrsInstall()
|
||||||
|
{
|
||||||
|
i86_IdtSetGate(0, (unsigned)i86_isr0, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(1, (unsigned)i86_isr1, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(2, (unsigned)i86_isr2, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(3, (unsigned)i86_isr3, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(4, (unsigned)i86_isr4, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(5, (unsigned)i86_isr5, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(6, (unsigned)i86_isr6, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(7, (unsigned)i86_isr7, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(8, (unsigned)i86_isr8, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(9, (unsigned)i86_isr9, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(10, (unsigned)i86_isr10, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(11, (unsigned)i86_isr11, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(12, (unsigned)i86_isr12, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(13, (unsigned)i86_isr13, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(14, (unsigned)i86_isr14, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(15, (unsigned)i86_isr15, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(16, (unsigned)i86_isr16, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(17, (unsigned)i86_isr17, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(18, (unsigned)i86_isr18, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(19, (unsigned)i86_isr19, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(20, (unsigned)i86_isr20, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(21, (unsigned)i86_isr21, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(22, (unsigned)i86_isr22, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(23, (unsigned)i86_isr23, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(24, (unsigned)i86_isr24, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(25, (unsigned)i86_isr25, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(26, (unsigned)i86_isr26, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(27, (unsigned)i86_isr27, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(28, (unsigned)i86_isr28, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(29, (unsigned)i86_isr29, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(30, (unsigned)i86_isr30, 0x08, 0x8E);
|
||||||
|
i86_IdtSetGate(31, (unsigned)i86_isr31, 0x08, 0x8E);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void i86_IsrsInstallHandler(int interr, void (*function)(ISR_stack_regs *r))
|
||||||
|
{
|
||||||
|
if (interr < 32) IdtFaultHandlers[interr] = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
void i86_IsrsUninstallHandler(int interr)
|
||||||
|
{
|
||||||
|
if (interr < 32) IdtFaultHandlers[interr] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All of our Exception handling Interrupt Service Routines will
|
||||||
|
* point to this function. This will tell us what exception has
|
||||||
|
* happened! Right now, we simply halt the system by hitting an
|
||||||
|
* endless loop. All ISRs disable interrupts while they are being
|
||||||
|
* serviced as a 'locking' mechanism to prevent an IRQ from
|
||||||
|
* happening and messing up kernel data structures */
|
||||||
|
void i86_FaultHandler(ISR_stack_regs *r)
|
||||||
|
{
|
||||||
|
/* Is this a fault whose number is from 0 to 31? */
|
||||||
|
if (r->int_no < 32)
|
||||||
|
{
|
||||||
|
void (*func)(ISR_stack_regs *r);
|
||||||
|
func = IdtFaultHandlers[r->int_no];
|
||||||
|
|
||||||
|
// Halt system if unhandled
|
||||||
|
if (!func) {
|
||||||
|
cprintf("%#0C*** %#0EFatal error: Unhandled interrupt (INT%u)", r->int_no);
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
else (*func)(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef __ISRS_H_
|
||||||
|
#define __ISRS_H_
|
||||||
|
|
||||||
|
extern void i86_IsrsInstall();
|
||||||
|
extern void i86_IsrsInstallHandler(int interr, void (*function)(ISR_stack_regs *r));
|
||||||
|
extern void i86_IsrsUninstallHandler(int interr);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include <system.h>
|
||||||
|
#include "cpu/cpu.h"
|
||||||
|
#include "clock/clock.h"
|
||||||
|
#include "floppy/floppy.h"
|
||||||
|
#include <drivers/keyboard.h>
|
||||||
|
//BSOD
|
||||||
|
|
||||||
|
extern void _STOP_ERROR_SCREEN(ISR_stack_regs *);
|
||||||
|
|
||||||
|
void DriversInstall()
|
||||||
|
{
|
||||||
|
// Initialize CPU stuff (GDT, IDT etc)
|
||||||
|
i86_CpuInitialize();
|
||||||
|
|
||||||
|
// Install default fault handler
|
||||||
|
int i;
|
||||||
|
for (i=0; i<32; i++)
|
||||||
|
i86_IsrsInstallHandler(i, _STOP_ERROR_SCREEN);
|
||||||
|
|
||||||
|
|
||||||
|
// Start installing keyboard
|
||||||
|
i86_IrqInstallHandler(1, i86_KeyboardHandler);
|
||||||
|
KeyboardInstallA();
|
||||||
|
|
||||||
|
// Install PIT
|
||||||
|
i86_PitInitialize(100);
|
||||||
|
i86_IrqInstallHandler(0, i86_PitHandler);
|
||||||
|
|
||||||
|
// Finish installing keyboard
|
||||||
|
KeyboardInstallB();
|
||||||
|
|
||||||
|
// Install floppy driver
|
||||||
|
asm volatile ("sti");
|
||||||
|
i86_IrqInstallHandler(6, i86_FloppyHandler);
|
||||||
|
FloppyInstall();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemShutDown()
|
||||||
|
{
|
||||||
|
i86_CpuShutdown();
|
||||||
|
// TODO: real shutdown
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemReboot()
|
||||||
|
{
|
||||||
|
unsigned char good = 0x02;
|
||||||
|
while ((good & 0x02) != 0)
|
||||||
|
good = inportb(0x64);
|
||||||
|
outportb(0x64, 0xFE);
|
||||||
|
|
||||||
|
asm volatile ("cli");
|
||||||
|
asm volatile ("hlt");
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef __DRIVERS__H__
|
||||||
|
#define __DRIVERS__H__
|
||||||
|
|
||||||
|
|
||||||
|
extern void DriversInstall();
|
||||||
|
extern void SystemShutDown();
|
||||||
|
extern void SystemReboot();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#include "../floppy/floppy.h"
|
||||||
|
//#include "vfs.h"
|
||||||
|
#include "fat.h"
|
||||||
|
|
||||||
|
#include <conio.h>
|
||||||
|
|
||||||
|
// Detect what FAT is used
|
||||||
|
unsigned FATDetect(unsigned TotalClusters)
|
||||||
|
{
|
||||||
|
if (TotalClusters == 0) return 0;
|
||||||
|
if (TotalClusters < 4085) return 12;
|
||||||
|
if (TotalClusters < 65525) return 16;
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*FatMountInfo FloppyMount(int drive)
|
||||||
|
{
|
||||||
|
FatMountInfo a;
|
||||||
|
FATBootSectorPointer fat = (FATBootSectorPointer)0x7e00;
|
||||||
|
FloppyReadSector((unsigned*)fat, drive, 0);
|
||||||
|
|
||||||
|
// Write mount info
|
||||||
|
a.FATEntrySize = 8;
|
||||||
|
a.FATOffset = 1;
|
||||||
|
a.FATSize = (unsigned)fat->SectorsPerFAT;
|
||||||
|
a.NumberOfRootEntries = (unsigned)fat->NumberOfDirectoryEntries;
|
||||||
|
a.NumberOfSectors = (unsigned)(fat->NumberOfSectors == 0) ? (fat->NumberOfSectorsLong) : (fat->NumberOfSectors);
|
||||||
|
a.RootOffset = (unsigned)(fat->NumberOfFATs)*a.FATSize + 1;
|
||||||
|
a.RootSize = (a.NumberOfRootEntries * 32) / (unsigned)fat->BytesPerSector;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}*/
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#ifndef __FAT_H__
|
||||||
|
#define __FAT_H__
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char Drive; //useless
|
||||||
|
unsigned char FlagsNT;
|
||||||
|
unsigned char Signature; // 0x28 or 0x29
|
||||||
|
unsigned SerialNumber;
|
||||||
|
char VolumeLabel[11];
|
||||||
|
char SysIDString[8]; // unreliable
|
||||||
|
} __attribute__((packed)) BPB_EXT_16;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned SectorsPerFAT;
|
||||||
|
unsigned short Flags;
|
||||||
|
unsigned short Version;
|
||||||
|
unsigned ClusterOfRootDirectory;
|
||||||
|
unsigned short ClusterOfFSInfo;
|
||||||
|
unsigned short ClusterOfBackupBootSector;
|
||||||
|
unsigned char Reserved[12]; // Should be 0 at format
|
||||||
|
unsigned char Drive;
|
||||||
|
unsigned char FlagsNT;
|
||||||
|
unsigned char Signature; // 0x28 or 0x29
|
||||||
|
unsigned SerialNumber;
|
||||||
|
char VolumeLabel[11];
|
||||||
|
char SysIDString[8]; // always FAT12
|
||||||
|
|
||||||
|
} __attribute__((packed)) BPB_EXT_32;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char _ignore[3];
|
||||||
|
|
||||||
|
// Bios Parameter Block
|
||||||
|
char OEMIdentify[8];
|
||||||
|
unsigned short BytesPerSector;
|
||||||
|
unsigned char SectorsPerCluster;
|
||||||
|
unsigned short ReservedSectors;
|
||||||
|
unsigned char NumberOfFATs;
|
||||||
|
unsigned short NumberOfDirectoryEntries;
|
||||||
|
unsigned short NumberOfSectors;
|
||||||
|
unsigned char MediaDescriptorType;
|
||||||
|
unsigned short SectorsPerFAT;
|
||||||
|
unsigned short SectorsPerTrack;
|
||||||
|
unsigned short HeadsPerCylinder;
|
||||||
|
unsigned HiddenSectors;
|
||||||
|
unsigned NumberOfSectorsLong;
|
||||||
|
|
||||||
|
union {
|
||||||
|
BPB_EXT_16 Ext16;
|
||||||
|
BPB_EXT_32 Ext32;
|
||||||
|
} Extended;
|
||||||
|
|
||||||
|
} __attribute__((packed)) FATBootSector, *FATBootSectorPointer;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned NumberOfSectors;
|
||||||
|
unsigned SizeOfSector;
|
||||||
|
unsigned FatOffset;
|
||||||
|
unsigned NumberOfRootEntries;
|
||||||
|
unsigned RootOffset;
|
||||||
|
unsigned SizeOfRoot;
|
||||||
|
unsigned SizeOfFat;
|
||||||
|
unsigned SizeOfFatEntry;
|
||||||
|
unsigned SizeOfCluster;
|
||||||
|
void (*ReadSector) (void* buffer, int lba);
|
||||||
|
} FatMountInfo, *FatMountInfoPointer;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char FileName[8];
|
||||||
|
char Extension[3];
|
||||||
|
unsigned char Atributes;
|
||||||
|
unsigned char Reserved;
|
||||||
|
unsigned char CreateTimeFine;
|
||||||
|
unsigned short CreateTime;
|
||||||
|
unsigned short CreateDate;
|
||||||
|
unsigned short LastAccessedDate;
|
||||||
|
unsigned short EAIndex;
|
||||||
|
unsigned short LastModifiedTime;
|
||||||
|
unsigned short LastModifiedDate;
|
||||||
|
unsigned short FirstCluster;
|
||||||
|
unsigned FileSize;
|
||||||
|
} __attribute__((packed)) FatDirectoryEntry, *FatDirectoryEntryPointer;
|
||||||
|
|
||||||
|
|
||||||
|
extern FatMountInfo FloppyMount(int drive);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#include "vfs.h"
|
||||||
|
#define MaxDevices 256
|
||||||
|
|
||||||
|
#define ReturnInvalid() { File ret; ret.Type = FileTypeInvalid; return ret;}
|
||||||
|
|
||||||
|
unsigned CurrentDevice = 0;
|
||||||
|
unsigned DeviceCount = 0;
|
||||||
|
|
||||||
|
FileSystemPointer _FileSystems[MaxDevices];
|
||||||
|
|
||||||
|
File VFSOpenFile (const char* FileName)
|
||||||
|
{
|
||||||
|
unsigned Device = CurrentDevice;
|
||||||
|
|
||||||
|
// No filename specified.
|
||||||
|
if (!FileName) ReturnInvalid();
|
||||||
|
|
||||||
|
// File length
|
||||||
|
int len = strlen(FileName);
|
||||||
|
// File name without drive
|
||||||
|
char* Name = 0;
|
||||||
|
|
||||||
|
// Check if relative or absolute path
|
||||||
|
int i;
|
||||||
|
for (i=0; i < len; i++)
|
||||||
|
if (FileName[i] == ':') {
|
||||||
|
Name = &FileName[i+1];
|
||||||
|
FileName[i] = 0;
|
||||||
|
len = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If absolute path, find device
|
||||||
|
if (Name != 0) {
|
||||||
|
for (i=0; i < MaxDevices; i++)
|
||||||
|
if (_FileSystems[i]) {
|
||||||
|
if (strcmp(_FileSystems[i]->Name, FileName) == 0) Device = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Drive is nonexistant or current drive not mounted
|
||||||
|
if (i==MaxDevices || !_FileSystems[Device]) ReturnInvalid();
|
||||||
|
|
||||||
|
// Open file
|
||||||
|
return _FileSystems[Device]->Open((Name) ? Name : FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int VFSInstallFileSystem(FileSystemPointer fs)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (!fs) return 0;
|
||||||
|
|
||||||
|
// Verify device does not exist
|
||||||
|
int i;
|
||||||
|
for (i=0; i < DeviceCount; i++)
|
||||||
|
if (_FileSystems[i])
|
||||||
|
if (strcmp (fs->Name, _FileSystems[i]->Name) == 0) return 0;
|
||||||
|
|
||||||
|
_FileSystems[DeviceCount] = fs; DeviceCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFSUninstallFileSystem(FileSystemPointer fs)
|
||||||
|
{
|
||||||
|
if (!fs) return;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i=0; i<DeviceCount; i++)
|
||||||
|
if (_FileSystems[i] == fs) {
|
||||||
|
_FileSystems[i] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFSUninstallFileSystemByName(const char* fs)
|
||||||
|
{
|
||||||
|
if (!fs) return;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i=0; i<DeviceCount; i++)
|
||||||
|
if (_FileSystems[i])
|
||||||
|
if (strcmp(_FileSystems[i]->Name, fs) == 0){
|
||||||
|
_FileSystems[i] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFSReadFile (FilePointer f, unsigned char* buffer, unsigned len)
|
||||||
|
{
|
||||||
|
if (!f || !_FileSystems[f->Device]) return;
|
||||||
|
_FileSystems[f->Device]->Read (f, buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFSCloseFile (FilePointer f)
|
||||||
|
{
|
||||||
|
if (!f || !_FileSystems[f->Device]) return;
|
||||||
|
_FileSystems[f->Device]->Close(f);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/***** vfs.h *********************************************************
|
||||||
|
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||||
|
* *
|
||||||
|
* Virtual File System (VFS) Implementation *
|
||||||
|
* ======================================== *
|
||||||
|
* *
|
||||||
|
************************************************************ cta os */
|
||||||
|
#ifndef __VFS__H___
|
||||||
|
#define __VFS__H___
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FileTypeInvalid,
|
||||||
|
FileTypeFile,
|
||||||
|
FileTypeDirectory,
|
||||||
|
FileTypeSymbolicLink
|
||||||
|
} FileType;
|
||||||
|
|
||||||
|
enum FileFlags {
|
||||||
|
FileFlagReadOnly = 0x1,
|
||||||
|
FileFlagHidden = 0x2,
|
||||||
|
FileFlagSystem = 0x4,
|
||||||
|
FileFlagVolumeID = 0x8,
|
||||||
|
FileFlagDirectory = 0x10,
|
||||||
|
FileFlagArchive = 0x20
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char Name[256];
|
||||||
|
FileType Type;
|
||||||
|
unsigned Flags;
|
||||||
|
unsigned Length;
|
||||||
|
unsigned EndOfFile;
|
||||||
|
unsigned ID;
|
||||||
|
unsigned Position, CurrentCluster;
|
||||||
|
unsigned Device;
|
||||||
|
TIME Created;
|
||||||
|
DATE LastAccessed;
|
||||||
|
TIME LastModified;
|
||||||
|
} File, *FilePointer;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char Name[256];
|
||||||
|
|
||||||
|
File (*Directory) (const char* DirectoryName);
|
||||||
|
void (*Mount) ();
|
||||||
|
void (*Read) (FilePointer, unsigned char*, unsigned);
|
||||||
|
void (*Close) (FilePointer);
|
||||||
|
FILE (*Open) (const char*);
|
||||||
|
|
||||||
|
} FileSystem, *FileSystemPointer;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/***** dma.c *********************************************************
|
||||||
|
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||||
|
* *
|
||||||
|
* Direct Memory Access (DMA) Routines *
|
||||||
|
* =================================== *
|
||||||
|
* *
|
||||||
|
************************************************************ cta os */
|
||||||
|
|
||||||
|
#include "dma.h"
|
||||||
|
#include <system.h>
|
||||||
|
|
||||||
|
enum DMA0InputOutput {
|
||||||
|
DMA0StatusRegister = 0x08,
|
||||||
|
DMA0CommandRegister = 0x08,
|
||||||
|
DMA0RequestRegister = 0x09,
|
||||||
|
DMA0ChannelMaskRegister = 0x0a,
|
||||||
|
DMA0ModeRegister = 0x0b,
|
||||||
|
DMA0ClearByteFlipFlopRegister = 0x0c,
|
||||||
|
DMA0TempRegister = 0x0d,
|
||||||
|
DMA0MasterClearRegister = 0x0d,
|
||||||
|
DMA0ClearMaskRegister = 0x0e,
|
||||||
|
DMA0MaskRegister = 0x0f
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DMA1InputOutput {
|
||||||
|
DMA1StatusRegister = 0xd0,
|
||||||
|
DMA1CommandRegister = 0xd0,
|
||||||
|
DMA1RequestRegister = 0xd2,
|
||||||
|
DMA1ChannelMaskRegister = 0xd4,
|
||||||
|
DMA1ModeRegister = 0xd6,
|
||||||
|
DMA1ClearByteFlipFlopRegister = 0xd8,
|
||||||
|
DMA1InterRegister = 0xda,
|
||||||
|
DMA1UnmaskAllRegister = 0xdc,
|
||||||
|
DMA1MaskRegister = 0xde
|
||||||
|
};
|
||||||
|
|
||||||
|
void DMASetAddress(unsigned short channel, unsigned char low, unsigned char high)
|
||||||
|
{
|
||||||
|
if (channel > 7) return; // Ignore if channel > 7
|
||||||
|
|
||||||
|
// Calculate port
|
||||||
|
unsigned short port = (channel >= 4) ? 4*(channel - 4) + 0xc0 : 2*channel;
|
||||||
|
|
||||||
|
// Set address
|
||||||
|
outportb (port, low);
|
||||||
|
outportb (port, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMASetCount (unsigned short channel, unsigned char low, unsigned char high)
|
||||||
|
{
|
||||||
|
if (channel > 7) return; // Ignore if channel > 7
|
||||||
|
|
||||||
|
// Calculate port
|
||||||
|
unsigned short port = (channel >= 4) ? 4*(channel - 4) + 0xc2
|
||||||
|
: (2*channel) + 1;
|
||||||
|
|
||||||
|
// Set count
|
||||||
|
outportb (port, low);
|
||||||
|
outportb (port, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMASetExternalPageRegisters (unsigned char channel, unsigned char val)
|
||||||
|
{
|
||||||
|
unsigned short port = 0;
|
||||||
|
|
||||||
|
switch (channel) {
|
||||||
|
case 1: port = 0x83; break;
|
||||||
|
case 2: port = 0x81; break;
|
||||||
|
case 3: port = 0x82; break;
|
||||||
|
// <- nothing should ever write to chan 4
|
||||||
|
case 5: port = 0x89; break;
|
||||||
|
case 6: port = 0x87; break;
|
||||||
|
case 7: port = 0x88; break;
|
||||||
|
default: if (channel == 4 || channel > 14) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
outportb(port, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMAMaskChannel (unsigned char channel)
|
||||||
|
{
|
||||||
|
if (channel <= 4) outportb (DMA0ChannelMaskRegister, (1<< (channel -1)));
|
||||||
|
else outportb (DMA1ChannelMaskRegister, (1<< (channel -5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMAUnmaskChannel (unsigned char channel)
|
||||||
|
{
|
||||||
|
if (channel <= 4) outportb (DMA0ChannelMaskRegister, channel);
|
||||||
|
else outportb (DMA1ChannelMaskRegister, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMAUnmaskAll()
|
||||||
|
{
|
||||||
|
outportb (DMA1UnmaskAllRegister, 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMAResetFlipFlop (unsigned char dma)
|
||||||
|
{
|
||||||
|
switch (dma) {
|
||||||
|
case 0: outportb (DMA0ClearByteFlipFlopRegister, 0xff);
|
||||||
|
case 1: outportb (DMA1ClearByteFlipFlopRegister, 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMAReset ()
|
||||||
|
{
|
||||||
|
outportb (DMA0TempRegister, 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMASetMode(unsigned char channel, unsigned char mode)
|
||||||
|
{
|
||||||
|
unsigned char dma = (channel < 4) ? 0:1;
|
||||||
|
unsigned char chan = (dma == 0) ? channel : channel-4;
|
||||||
|
|
||||||
|
DMAMaskChannel (channel);
|
||||||
|
outportb ((channel < 4) ? DMA0ModeRegister : DMA1ModeRegister, chan | mode);
|
||||||
|
DMAUnmaskAll ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMASetRead (unsigned char channel)
|
||||||
|
{
|
||||||
|
DMASetMode (channel, DMAModeReadTransfer | DMAModeTransferSingle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DMASetWrite (unsigned char channel)
|
||||||
|
{
|
||||||
|
DMASetMode (channel, DMAModeWriteTransfer | DMAModeTransferSingle);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/***** dma.h *********************************************************
|
||||||
|
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||||
|
* *
|
||||||
|
* Direct Memory Access (DMA) Routines *
|
||||||
|
* =================================== *
|
||||||
|
* *
|
||||||
|
************************************************************ cta os */
|
||||||
|
|
||||||
|
#ifndef __DMA__H__
|
||||||
|
#define __DMA__H__
|
||||||
|
|
||||||
|
enum DMA_MODE_REG_MASK {
|
||||||
|
DMAModeMaskSelect = 3,
|
||||||
|
|
||||||
|
DMAModeMaskTra = 0xc,
|
||||||
|
DMAModeSelfTest = 0,
|
||||||
|
DMAModeReadTransfer = 4,
|
||||||
|
DMAModeWriteTransfer = 8,
|
||||||
|
|
||||||
|
DMAModeMaskAuto = 0x10,
|
||||||
|
DMAModeMaskIdec = 0x20,
|
||||||
|
|
||||||
|
DMAModeMask = 0xc0,
|
||||||
|
DMAModeTransferOnDemand = 0,
|
||||||
|
DMAModeTransferSingle = 0x40,
|
||||||
|
DMAModeTransferBlock = 0x80,
|
||||||
|
DMAModeTransferCascade = 0xC0
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void DMASetAddress(unsigned short channel, unsigned char low, unsigned char high);
|
||||||
|
extern void DMASetCount (unsigned short channel, unsigned char low, unsigned char high);
|
||||||
|
extern void DMASetExternalPageRegisters (unsigned char channel, unsigned char val);
|
||||||
|
extern void DMAMaskChannel (unsigned char channel);
|
||||||
|
extern void DMAUnmaskChannel (unsigned char channel);
|
||||||
|
extern void DMAUnmaskAll();
|
||||||
|
extern void DMAResetFlipFlop (unsigned char dma);
|
||||||
|
extern void DMAReset ();
|
||||||
|
extern void DMASetMode(unsigned char channel, unsigned char mode);
|
||||||
|
extern void DMASetRead (unsigned char channel);
|
||||||
|
extern void DMASetWrite (unsigned char channel);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,494 @@
|
|||||||
|
/***** floppy.c ******************************************************
|
||||||
|
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||||
|
* *
|
||||||
|
* Floppy Drive I/O Routines *
|
||||||
|
* ========================= *
|
||||||
|
* *
|
||||||
|
************************************************************ cta os */
|
||||||
|
#include <system.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "dma.h"
|
||||||
|
#include "storage.h"
|
||||||
|
|
||||||
|
unsigned char CmosReadFloppyData ()
|
||||||
|
{
|
||||||
|
outportb (0x70, 0x10);
|
||||||
|
return inportb(0x71);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char FloppyDrivesInstalled;
|
||||||
|
volatile unsigned char FloppyNewInterrupt;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char Type;
|
||||||
|
unsigned Size;
|
||||||
|
unsigned char SectorsPerTrack;
|
||||||
|
unsigned char Heads;
|
||||||
|
unsigned char Tracks;
|
||||||
|
unsigned char DataRate;
|
||||||
|
unsigned char StepRateTime;
|
||||||
|
unsigned char HeadLoadTime;
|
||||||
|
unsigned char HeadUnloadTime;
|
||||||
|
unsigned char Gap3;
|
||||||
|
unsigned char Gap3Format;
|
||||||
|
} FloppyType;
|
||||||
|
|
||||||
|
FloppyType fd[2];
|
||||||
|
|
||||||
|
void FloppyReset();
|
||||||
|
enum FloppyRegisters {
|
||||||
|
FloppyRegDOR = 0x3f2,
|
||||||
|
FloppyRegMSR = 0x3f4,
|
||||||
|
FloppyRegFIFO = 0x3f5,
|
||||||
|
FloppyRegCTRL = 0x3f7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FloppyCommands {
|
||||||
|
FloppyCommandReadTrack = 2,
|
||||||
|
FloppyCommandSpecify = 3,
|
||||||
|
FloppyCommandCheckStatus = 4,
|
||||||
|
FloppyCommandWriteSector = 5,
|
||||||
|
FloppyCommandReadSector = 6,
|
||||||
|
FloppyCommandCalibrate = 7,
|
||||||
|
FloppyCommandCheckInt = 8,
|
||||||
|
FloppyCommandFormatTrack = 0xd,
|
||||||
|
FloppyCommandSeek = 0xf,
|
||||||
|
|
||||||
|
FloppyCommandExtSkip = 0x20,
|
||||||
|
FloppyCommandExtDensity = 0x40,
|
||||||
|
FloppyCommandExtMultiTrack = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize DMA
|
||||||
|
unsigned char FloppyInitializeDMA(unsigned char* buffer, unsigned length)
|
||||||
|
{
|
||||||
|
union { unsigned char byt[4]; // Low[0], Mid[1], Hi[2]
|
||||||
|
unsigned long l;
|
||||||
|
} a, c;
|
||||||
|
|
||||||
|
a.l = (unsigned) buffer;
|
||||||
|
c.l = (unsigned) length-1;
|
||||||
|
|
||||||
|
// Check for buffer issues
|
||||||
|
if ((a.l >> 24) || (c.l >> 16) || (((a.l & 0xffff)+c.l) >> 16)) return 0;
|
||||||
|
|
||||||
|
DMAReset();
|
||||||
|
DMAMaskChannel(2); // Mask channel 2
|
||||||
|
DMAResetFlipFlop(1); // FlipFlop reset on DMA1
|
||||||
|
|
||||||
|
DMASetAddress(2, a.byt[0], a.byt[1]); // Buffer address
|
||||||
|
DMAResetFlipFlop(1); // FlipFlop reset on DMA2
|
||||||
|
|
||||||
|
DMASetCount(2, c.byt[0], c.byt[1]); // Set count
|
||||||
|
DMASetRead(2);
|
||||||
|
DMAUnmaskAll();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void FloppyDisableController() {
|
||||||
|
outportb (FloppyRegDOR, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void FloppyEnableController() {
|
||||||
|
outportb (FloppyRegDOR, 4 | 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline unsigned char FloppySendCommand (unsigned char command)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 750; i++)
|
||||||
|
if (inportb(FloppyRegMSR) & 128) {
|
||||||
|
outportb(FloppyRegFIFO, command); return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline unsigned char FloppyReadData ()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 750; i++)
|
||||||
|
if (inportb(FloppyRegMSR) & 0x80)
|
||||||
|
return inportb(FloppyRegFIFO);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void FloppyCheckInt(unsigned* st0, unsigned* cyl)
|
||||||
|
{
|
||||||
|
int t;
|
||||||
|
for (t=3; t>=0; t--) {
|
||||||
|
if (!FloppySendCommand(0x8)) FloppyReset();
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
for (t=50; !(inportb(FloppyRegMSR) & 0x80) && t>0; --t);
|
||||||
|
|
||||||
|
*st0 = FloppyReadData();
|
||||||
|
*cyl = FloppyReadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline unsigned char FloppyWaitIRQ()
|
||||||
|
{
|
||||||
|
unsigned tick = ClockGetTickCount();
|
||||||
|
unsigned freq = PitGetFrequency();
|
||||||
|
tick = tick + (freq * 3); // Wait 3 seconds
|
||||||
|
|
||||||
|
while (FloppyNewInterrupt==0)
|
||||||
|
if (tick <= ClockGetTickCount()) return 0; // timeout
|
||||||
|
|
||||||
|
FloppyNewInterrupt = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FloppyMotor (unsigned char drive, unsigned char on)
|
||||||
|
{
|
||||||
|
if (drive >= FloppyDrivesInstalled) return;
|
||||||
|
|
||||||
|
// Read DOR register
|
||||||
|
unsigned char dor = inportb(FloppyRegDOR);
|
||||||
|
|
||||||
|
// Un/set selected drive motor
|
||||||
|
if (on) dor |= 1 << (4+drive);
|
||||||
|
else dor &= ~(1 << (4+drive));
|
||||||
|
|
||||||
|
// Write DOR
|
||||||
|
outportb (FloppyRegDOR, dor);
|
||||||
|
|
||||||
|
// Wait a fifth of a second for motor to turn on
|
||||||
|
unsigned temp = ClockGetTickCount();
|
||||||
|
unsigned freq = PitGetFrequency();
|
||||||
|
while (temp + (freq/5) > ClockGetTickCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void i86_FloppyHandler(ISR_stack_regs *r)
|
||||||
|
{
|
||||||
|
FloppyNewInterrupt = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FloppyDriveData (unsigned char drv, unsigned char dma)
|
||||||
|
{
|
||||||
|
unsigned data = 0;
|
||||||
|
if (drv >= FloppyDrivesInstalled) return;
|
||||||
|
|
||||||
|
outportb(FloppyRegCTRL, fd[drv].DataRate);
|
||||||
|
|
||||||
|
FloppySendCommand (0x3);
|
||||||
|
|
||||||
|
data = ((fd[drv].StepRateTime & 0xf) << 4) | (fd[drv].HeadUnloadTime & 0xf);
|
||||||
|
FloppySendCommand (data);
|
||||||
|
|
||||||
|
data = (fd[drv].HeadLoadTime <<1 ) | (dma) ? 1 : 0;
|
||||||
|
FloppySendCommand (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void FloppySelect(unsigned char drive)
|
||||||
|
{
|
||||||
|
if (drive >= FloppyDrivesInstalled) return;
|
||||||
|
|
||||||
|
unsigned char dor = inportb(FloppyRegDOR) & 0xf0;
|
||||||
|
|
||||||
|
// Send mechanical drive data
|
||||||
|
FloppyDriveData(drive, 1);
|
||||||
|
|
||||||
|
// Select drive in DOR register
|
||||||
|
outportb (FloppyRegDOR, dor | 4 | 8 | drive);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char FloppyCalibrate(unsigned drive)
|
||||||
|
{
|
||||||
|
unsigned st0, cyl;
|
||||||
|
|
||||||
|
if (drive >= FloppyDrivesInstalled) return 0;
|
||||||
|
|
||||||
|
FloppyMotor (drive, 1);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 15; i++) {
|
||||||
|
FloppyNewInterrupt = 0;
|
||||||
|
FloppySendCommand(FloppyCommandCalibrate);
|
||||||
|
FloppySendCommand(drive);
|
||||||
|
FloppyWaitIRQ();
|
||||||
|
FloppyCheckInt(&st0, &cyl);
|
||||||
|
|
||||||
|
if (!cyl) {
|
||||||
|
FloppyMotor(drive, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FloppyMotor(drive, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FloppyReset()
|
||||||
|
{
|
||||||
|
unsigned st0, cyl;
|
||||||
|
|
||||||
|
FloppyNewInterrupt = 0;
|
||||||
|
FloppyDisableController();
|
||||||
|
FloppyEnableController();
|
||||||
|
FloppyWaitIRQ();
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
FloppyCheckInt(&st0, &cyl);
|
||||||
|
|
||||||
|
unsigned char drive;
|
||||||
|
for (drive = 0; drive < FloppyDrivesInstalled; drive++) {
|
||||||
|
FloppyDriveData(drive, 1);
|
||||||
|
FloppyCalibrate(drive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned FloppyReadSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector)
|
||||||
|
{
|
||||||
|
int t, fail;
|
||||||
|
for (t=3; t>=0; t--) {
|
||||||
|
fail = 0;
|
||||||
|
FloppySelect (drive);
|
||||||
|
FloppyInitializeDMA((unsigned char*) where, 512);
|
||||||
|
DMASetRead(2);
|
||||||
|
|
||||||
|
FloppyNewInterrupt = 0;
|
||||||
|
|
||||||
|
fail += 1-FloppySendCommand(0x06 | 0x80 | 0x40 );
|
||||||
|
fail += 1-FloppySendCommand(head<<2 | drive);
|
||||||
|
fail += 1-FloppySendCommand(track);
|
||||||
|
fail += 1-FloppySendCommand(head);
|
||||||
|
fail += 1-FloppySendCommand(sector);
|
||||||
|
fail += 1-FloppySendCommand(2);
|
||||||
|
fail += 1-FloppySendCommand( ((sector+1) >= fd[drive].SectorsPerTrack) ? fd[drive].SectorsPerTrack : sector+1);
|
||||||
|
fail += 1-FloppySendCommand(fd[drive].Gap3);
|
||||||
|
fail += 1-FloppySendCommand(0xff);
|
||||||
|
|
||||||
|
if (fail) {
|
||||||
|
FloppyReset(); continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FloppyWaitIRQ();
|
||||||
|
while (!(inportb(FloppyRegMSR) & 0x80));
|
||||||
|
|
||||||
|
int i; unsigned ccc=0;
|
||||||
|
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
if (i<3) ccc |= FloppyReadData() << (i*4);
|
||||||
|
else FloppyReadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ccc;
|
||||||
|
}
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned FloppyWriteSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector)
|
||||||
|
{
|
||||||
|
int t, fail;
|
||||||
|
for (t=3; t>=0; t--) {
|
||||||
|
fail = 0;
|
||||||
|
FloppySelect (drive);
|
||||||
|
FloppyInitializeDMA((unsigned char*) where, 512);
|
||||||
|
DMASetWrite(2);
|
||||||
|
|
||||||
|
FloppyNewInterrupt = 0;
|
||||||
|
|
||||||
|
fail += 1-FloppySendCommand(0x05 | 0x80 | 0x40 );
|
||||||
|
fail += 1-FloppySendCommand(head<<2 | drive);
|
||||||
|
fail += 1-FloppySendCommand(track);
|
||||||
|
fail += 1-FloppySendCommand(head);
|
||||||
|
fail += 1-FloppySendCommand(sector);
|
||||||
|
fail += 1-FloppySendCommand(2);
|
||||||
|
fail += 1-FloppySendCommand( ((sector+1) >= fd[drive].SectorsPerTrack) ? fd[drive].SectorsPerTrack : sector+1);
|
||||||
|
fail += 1-FloppySendCommand(fd[drive].Gap3);
|
||||||
|
fail += 1-FloppySendCommand(0xff);
|
||||||
|
|
||||||
|
if (fail) {
|
||||||
|
FloppyReset(); continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FloppyWaitIRQ();
|
||||||
|
|
||||||
|
int i; unsigned ccc=0;
|
||||||
|
for (i = 0; i < 7; i++)
|
||||||
|
if (i<3) ccc |= FloppyReadData() << (i*4);
|
||||||
|
else FloppyReadData();
|
||||||
|
|
||||||
|
return ccc;
|
||||||
|
}
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char FloppySeek (unsigned drive, unsigned cyl, unsigned head)
|
||||||
|
{
|
||||||
|
unsigned st0, cyl0;
|
||||||
|
|
||||||
|
if (drive >= FloppyDrivesInstalled) return 0;
|
||||||
|
|
||||||
|
FloppySelect (drive);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 20; i++) {
|
||||||
|
FloppyNewInterrupt = 0;
|
||||||
|
FloppySendCommand (0xF);
|
||||||
|
FloppySendCommand ( (head) << 2 | drive);
|
||||||
|
FloppySendCommand (cyl);
|
||||||
|
|
||||||
|
FloppyWaitIRQ();
|
||||||
|
FloppyCheckInt(&st0, &cyl0);
|
||||||
|
|
||||||
|
if (cyl0 == cyl) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void FloppyLBAtoCHS (int lba, unsigned char drive, unsigned char *head, unsigned char *track, unsigned char *sectors)
|
||||||
|
{
|
||||||
|
*head = (lba % (fd[drive].SectorsPerTrack * 2)) / fd[drive].SectorsPerTrack;
|
||||||
|
*track = lba / (fd[drive].SectorsPerTrack * 2);
|
||||||
|
*sectors = lba % fd[drive].SectorsPerTrack + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*const char* types[] = {
|
||||||
|
"Nonexistant", "5.25\", unsupported.", "5.25\", unsupported.",
|
||||||
|
"3.5\", 720kb", "3.5\", 1.44mb", "3.5\", 2.88 mb"};*/
|
||||||
|
|
||||||
|
void FloppyInstall()
|
||||||
|
{
|
||||||
|
unsigned char temp = CmosReadFloppyData();
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Set fd0 and fd1 types
|
||||||
|
fd[1].Type = temp & 0xf;
|
||||||
|
fd[0].Type = temp >> 4;
|
||||||
|
|
||||||
|
// SRT = 16 - (ms * datarate / 500000);
|
||||||
|
// HLT = ms * datarate / 1000000
|
||||||
|
// HUT = ms * datarate / 8000000
|
||||||
|
|
||||||
|
// Set up
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
if (fd[i].Type >= 3) FloppyDrivesInstalled++; // 5.25" drives unsupported
|
||||||
|
if (fd[i].Type == 3) { // 720 kb, DD
|
||||||
|
fd[i].DataRate = 2; // speed = 250 kbps
|
||||||
|
fd[i].StepRateTime = 12; // 16 - (ms * 250000 / 500000), ms = 8
|
||||||
|
fd[i].HeadLoadTime = 7;
|
||||||
|
fd[i].HeadUnloadTime = 7;
|
||||||
|
fd[i].SectorsPerTrack = 9;
|
||||||
|
fd[i].Size = 1440;
|
||||||
|
fd[i].Gap3 = 0x2A;
|
||||||
|
fd[i].Gap3Format = 0x50;
|
||||||
|
fd[i].Heads = 2;
|
||||||
|
fd[i].Tracks = 80;
|
||||||
|
}
|
||||||
|
else if (fd[i].Type == 4) { // 1.44 MB, HD
|
||||||
|
fd[i].DataRate = 0; // speed = 500 kbps
|
||||||
|
fd[i].StepRateTime = 8;
|
||||||
|
fd[i].HeadLoadTime = 15;
|
||||||
|
fd[i].HeadUnloadTime = 15;
|
||||||
|
fd[i].SectorsPerTrack = 18;
|
||||||
|
fd[i].Size = 2880;
|
||||||
|
fd[i].Gap3 = 0x1B;
|
||||||
|
fd[i].Gap3Format = 0x6C;
|
||||||
|
fd[i].Heads = 2;
|
||||||
|
fd[i].Tracks = 80;
|
||||||
|
}
|
||||||
|
else if (fd[i].Type == 5) { // 2.88 MB, ED
|
||||||
|
fd[i].DataRate = 3; // speed = 1000 kbps;
|
||||||
|
fd[i].StepRateTime = 0;
|
||||||
|
fd[i].HeadLoadTime = 30;
|
||||||
|
fd[i].HeadUnloadTime = 30;
|
||||||
|
fd[i].SectorsPerTrack = 36;
|
||||||
|
fd[i].Size = 5760;
|
||||||
|
fd[i].Gap3 = 0x1B;
|
||||||
|
fd[i].Gap3Format = 0x54;
|
||||||
|
fd[i].Heads = 2;
|
||||||
|
fd[i].Tracks = 80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FloppyDrivesInstalled == 0) return; // No drives to set
|
||||||
|
|
||||||
|
|
||||||
|
FloppyReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char FloppyIsDriverEnabled()
|
||||||
|
{
|
||||||
|
return FloppyDrivesInstalled;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned* FloppyReadSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count)
|
||||||
|
{
|
||||||
|
if (drive >= FloppyDrivesInstalled || !where) return 0;
|
||||||
|
|
||||||
|
unsigned head=0, track=0, sector=1, i, addr = (unsigned)where;
|
||||||
|
|
||||||
|
// start motor, seek to track
|
||||||
|
FloppyMotor(drive, 1);
|
||||||
|
|
||||||
|
// read count sectors
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
|
||||||
|
// Convert lba to chs
|
||||||
|
head=0, track=0, sector=1;
|
||||||
|
FloppyLBAtoCHS(sectorLBA+i, drive, (unsigned char*)&head, (unsigned char*)&track, (unsigned char*) §or);
|
||||||
|
|
||||||
|
// Seek
|
||||||
|
if (!FloppySeek(drive, track, head)) return 0;
|
||||||
|
|
||||||
|
// Read the sector
|
||||||
|
FloppyReadSectorImp((unsigned*)0x7e00, drive, head, track, sector);
|
||||||
|
|
||||||
|
memcpy((void*)(addr+(0x200*i)), (void*)0x7e00, 0x200);
|
||||||
|
}
|
||||||
|
|
||||||
|
FloppyMotor(drive, 0);
|
||||||
|
|
||||||
|
return (unsigned*)where;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned* FloppyWriteSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count)
|
||||||
|
{
|
||||||
|
if (drive >= FloppyDrivesInstalled || !where) return 0;
|
||||||
|
|
||||||
|
unsigned head=0, track=0, sector=1, i, addr = (unsigned)where;
|
||||||
|
|
||||||
|
// start motor, seek to track
|
||||||
|
FloppyMotor(drive, 1);
|
||||||
|
|
||||||
|
// read count sectors
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
memcpy((void*)0x7e00, (void*)(addr+(0x200*i)), 0x200);
|
||||||
|
where = where+0x200;
|
||||||
|
// Convert lba to chs
|
||||||
|
head=0, track=0, sector=1;
|
||||||
|
FloppyLBAtoCHS(sectorLBA+i, drive, (unsigned char*)&head, (unsigned char*)&track, (unsigned char*) §or);
|
||||||
|
|
||||||
|
// Seek
|
||||||
|
if (!FloppySeek(drive, track, head)) return 0;
|
||||||
|
|
||||||
|
// Read the sector
|
||||||
|
FloppyWriteSectorImp((unsigned*)0x7e00, drive, head, track, sector);
|
||||||
|
}
|
||||||
|
|
||||||
|
FloppyMotor(drive, 0);
|
||||||
|
|
||||||
|
return (unsigned*)where;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/***** floppy.h ******************************************************
|
||||||
|
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||||
|
* *
|
||||||
|
* Floppy Drive I/O Routines *
|
||||||
|
* ========================= *
|
||||||
|
* *
|
||||||
|
************************************************************ cta os */
|
||||||
|
#include<regs.h>
|
||||||
|
|
||||||
|
extern unsigned char FloppyInitializeDMA(unsigned char* buffer, unsigned length);
|
||||||
|
extern void FloppyMotor (unsigned char drive, unsigned char on);
|
||||||
|
extern void i86_FloppyHandler(ISR_stack_regs *r);
|
||||||
|
extern void FloppyDriveData (unsigned char drv, unsigned char dma);
|
||||||
|
extern unsigned char FloppyCalibrate(unsigned drive);
|
||||||
|
extern void FloppyReset();
|
||||||
|
|
||||||
|
extern unsigned char FloppySeek (unsigned drive, unsigned cyl, unsigned head);
|
||||||
|
extern void FloppyInstall();
|
||||||
|
extern unsigned char FloppyIsDriverEnabled();
|
||||||
|
|
||||||
|
// Read/Write routines
|
||||||
|
extern unsigned* FloppyReadSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count);
|
||||||
|
extern unsigned* FloppyWriteSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count);
|
||||||
|
|
||||||
|
extern void FloppyReadSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector);
|
||||||
|
extern void FloppyWritedSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector);
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __STORAGE__H__
|
||||||
|
#define __STORAGE__H__
|
||||||
|
|
||||||
|
/**Structure used by the file system drivers.\n
|
||||||
|
\Warning: the driver that provides the Read/Write routines must
|
||||||
|
include conversions for partitions on hard drives.*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned NumberOfSectors;
|
||||||
|
unsigned SizeOfSector;
|
||||||
|
void (*ReadSectors) (void* buffer, int startlba, int endlba);
|
||||||
|
void (*WriteSectors) (void* buffer, int startlba, int endlba);
|
||||||
|
} StorageDeviceInterface, *StorageDeviceInterfacePointer;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
@echo off
|
@echo off
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
rem NASM and DJGPP executable paths:
|
||||||
set nasm_path=C:\nasm
|
set nasm_path=C:\nasm
|
||||||
set djgpp_path=C:\DJGPP\bin
|
set djgpp_path=C:\mingw\bin
|
||||||
set objpath=../../objects
|
set objpath=../../objects
|
||||||
set incpath=../../include
|
set incpath=../../include
|
||||||
|
|
||||||
@echo on
|
@echo on
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/dma.o dma.c
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/drivers/keyboard.o keyboard.c
|
||||||
|
|
||||||
@echo off
|
@echo off
|
||||||
@echo .
|
@echo .
|
||||||
@@ -1,11 +1,7 @@
|
|||||||
#include <system.h>
|
#include <system.h>
|
||||||
#include <hal.h>
|
#include <drivers/keyboard.h>
|
||||||
#include "keyus.h"
|
|
||||||
#include "../irq/irq.h"
|
|
||||||
|
|
||||||
extern void reboot();
|
const char KeyMap[] = {
|
||||||
|
|
||||||
const char kbdus_map[] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0,
|
||||||
0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0,
|
0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0,
|
||||||
0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
|
0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
|
||||||
@@ -16,7 +12,7 @@ const char kbdus_map[] = {
|
|||||||
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
const char kbdus_map_shift[] = {
|
const char KeyMapShift[] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0,
|
||||||
0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
|
0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
|
||||||
0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
|
0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
|
||||||
@@ -27,116 +23,114 @@ const char kbdus_map_shift[] = {
|
|||||||
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
volatile unsigned char KeyArray[16];
|
||||||
volatile unsigned char kb_array[16];
|
volatile unsigned char KeyboardNewData;
|
||||||
volatile unsigned char kb_newdata;
|
volatile unsigned char KeyModifierStatus;
|
||||||
volatile unsigned char kb_modifier_status;
|
volatile unsigned char KeyScancodePrefix;
|
||||||
volatile unsigned char kb_prefix;
|
volatile unsigned char KeyLightsStatus;
|
||||||
volatile unsigned char kb_lights_status;
|
unsigned char KeyboardScancodeSet;
|
||||||
unsigned char kb_scancode_set;
|
|
||||||
|
|
||||||
|
|
||||||
void i86_kb_set_key(unsigned char scancode, unsigned char val)
|
void KeyboardSetKey(unsigned char scancode, unsigned char val)
|
||||||
{
|
{
|
||||||
unsigned char pos = scancode/8;
|
unsigned char pos = scancode/8;
|
||||||
unsigned char offset = scancode%8;
|
unsigned char offset = scancode%8;
|
||||||
|
|
||||||
if (val) {
|
if (val) {
|
||||||
kb_array[pos] |= 1<<offset;
|
KeyArray[pos] |= 1<<offset;
|
||||||
kb_newdata = scancode;
|
KeyboardNewData = scancode;
|
||||||
}
|
}
|
||||||
else kb_array[pos] &= 0xFF - (1<<offset);
|
else KeyArray[pos] &= 0xFF - (1<<offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char i86_kb_get_key(unsigned char scancode)
|
unsigned char KeyIsPressed(unsigned char scancode)
|
||||||
{
|
{
|
||||||
unsigned char pos = scancode/8;
|
unsigned char pos = scancode/8;
|
||||||
unsigned char offset = scancode%8;
|
unsigned char offset = scancode%8;
|
||||||
return (kb_array[pos]&(1<<offset));
|
return (KeyArray[pos]&(1<<offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i86_kb_handler(ISR_stack_regs *r) {
|
void i86_KeyboardHandler(ISR_stack_regs *r) {
|
||||||
unsigned char scancode = inportb(0x60);
|
unsigned char scancode = inportb(0x60);
|
||||||
|
|
||||||
switch (scancode) {
|
switch (scancode) {
|
||||||
case 0x00: // Error 0x00
|
case 0x00: // Error 0x00
|
||||||
case 0xFC: // Diagnostics failed (MF kb)
|
case 0xFC: // Diagnostics failed (MF kb)
|
||||||
case 0xFD: // Diagnostics failed (AT kb)
|
case 0xFD: // Diagnostics failed (AT kb)
|
||||||
case 0xFF: i86_kb_waitin(); outportb(0x60, 0xF4); // Error 0xFF
|
case 0xFF: KeyboardWaitInput(); outportb(0x60, 0xF4); // Error 0xFF
|
||||||
break;
|
break;
|
||||||
case 0xAA: // BAT test successful.
|
case 0xAA: // BAT test successful.
|
||||||
case 0xFA: // ACKnowledge
|
case 0xFA: // ACKnowledge
|
||||||
case 0xFE: // Last command invalid or parity error
|
case 0xFE: // Last command invalid or parity error
|
||||||
case 0xEE: break; // Echo response
|
case 0xEE: break; // Echo response
|
||||||
// Gray or break
|
// Gray or break
|
||||||
case 0xE0: kb_prefix |= 1; break;
|
case 0xE0: KeyScancodePrefix |= 1; break;
|
||||||
case 0xE1: kb_prefix |= 4; break;
|
case 0xE1: KeyScancodePrefix |= 4; break;
|
||||||
case 0xF0: kb_prefix |= 2; break;
|
case 0xF0: KeyScancodePrefix |= 2; break;
|
||||||
|
|
||||||
// Alt, ctrl...
|
// Alt, ctrl...
|
||||||
case 0x11: if ((kb_prefix&1) == 0) { // Left alt
|
case 0x11: if ((KeyScancodePrefix&1) == 0) { // Left alt
|
||||||
if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<2;
|
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<2;
|
||||||
else kb_modifier_status &= 0xFF - (1<<2);
|
else KeyModifierStatus &= 0xFF - (1<<2);
|
||||||
}
|
}
|
||||||
else { // Right alt
|
else { // Right alt
|
||||||
if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<3;
|
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<3;
|
||||||
else kb_modifier_status &= 0xFF - (1<<3);
|
else KeyModifierStatus &= 0xFF - (1<<3);
|
||||||
}
|
}
|
||||||
kb_prefix = 0; break;
|
KeyScancodePrefix = 0; break;
|
||||||
|
|
||||||
case 0x12: if ((kb_prefix&1) == 0) { // Left shift
|
case 0x12: if ((KeyScancodePrefix&1) == 0) { // Left shift
|
||||||
if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<0;
|
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<0;
|
||||||
else kb_modifier_status &= 0xFF - (1<<0);
|
else KeyModifierStatus &= 0xFF - (1<<0);
|
||||||
}
|
}
|
||||||
else { // Fake shift
|
else { // Fake shift
|
||||||
if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<6;
|
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<6;
|
||||||
else kb_modifier_status &= 0xFF - (1<<6);
|
else KeyModifierStatus &= 0xFF - (1<<6);
|
||||||
}
|
}
|
||||||
kb_prefix = 0; break;
|
KeyScancodePrefix = 0; break;
|
||||||
|
|
||||||
case 0x14: if (kb_prefix&4) {
|
case 0x14: if (KeyScancodePrefix&4) { // Pause/break
|
||||||
if ((kb_prefix&2) == 0) i86_kb_set_key (0, 1);
|
if ((KeyScancodePrefix&2) == 0) KeyboardSetKey (0, 1);
|
||||||
else i86_kb_set_key (0, 0);
|
else KeyboardSetKey (0, 0);
|
||||||
kb_prefix |= 8; break;
|
KeyScancodePrefix |= 8; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((kb_prefix&1) == 0) { // Left ctrl
|
else if ((KeyScancodePrefix&1) == 0) { // Left ctrl
|
||||||
if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<4;
|
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<4;
|
||||||
else kb_modifier_status &= 0xFF - (1<<4);
|
else KeyModifierStatus &= 0xFF - (1<<4);
|
||||||
}
|
}
|
||||||
else { // Right ctrl
|
else { // Right ctrl
|
||||||
if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<5;
|
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<5;
|
||||||
else kb_modifier_status &= 0xFF - (1<<5);
|
else KeyModifierStatus &= 0xFF - (1<<5);
|
||||||
}
|
}
|
||||||
kb_prefix = 0; break;
|
KeyScancodePrefix = 0; break;
|
||||||
|
|
||||||
case 0x59: // Right shift
|
case 0x59: // Right shift
|
||||||
if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<1;
|
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<1;
|
||||||
else kb_modifier_status &= 0xFF - (1<<1);
|
else KeyModifierStatus &= 0xFF - (1<<1);
|
||||||
|
|
||||||
kb_prefix = 0; break;
|
KeyScancodePrefix = 0; break;
|
||||||
|
|
||||||
// LEDs
|
// LEDs
|
||||||
case 0x58: if ((kb_prefix&2) == 0) {
|
case 0x58: if ((KeyScancodePrefix&2) == 0) {
|
||||||
kb_lights_status ^= 4; i86_kb_set_LEDs(kb_lights_status);
|
KeyLightsStatus ^= 4; KeyboardSetLEDs(KeyLightsStatus);
|
||||||
} kb_prefix = 0; break; // Caps
|
} KeyScancodePrefix = 0; break; // Caps
|
||||||
|
|
||||||
//TO ADD BELOW: pause/break byte2
|
|
||||||
case 0x77:
|
case 0x77:
|
||||||
if ((kb_prefix&4) && (kb_prefix&8)) kb_prefix=0;
|
if ((KeyScancodePrefix&4) && (KeyScancodePrefix&8)) KeyScancodePrefix=0;
|
||||||
else if ((kb_prefix&2) == 0) {
|
else if ((KeyScancodePrefix&2) == 0) {
|
||||||
kb_lights_status ^= 2; i86_kb_set_LEDs(kb_lights_status);
|
KeyLightsStatus ^= 2; KeyboardSetLEDs(KeyLightsStatus);
|
||||||
} kb_prefix = 0; break; // Num
|
} KeyScancodePrefix = 0; break; // Num
|
||||||
case 0x7E: if ((kb_prefix&2) == 0) {
|
case 0x7E: if ((KeyScancodePrefix&2) == 0) {
|
||||||
kb_lights_status ^= 1; i86_kb_set_LEDs(kb_lights_status);
|
KeyLightsStatus ^= 1; KeyboardSetLEDs(KeyLightsStatus);
|
||||||
} kb_prefix = 0; break; // Scroll
|
} KeyScancodePrefix = 0; break; // Scroll
|
||||||
|
|
||||||
case 0x83: scancode = 0x02; // Put F7 under the 0x80 (128bit) barrier
|
case 0x83: scancode = 0x02; // Put F7 under the 0x80 (128bit) barrier
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Remap gray keys
|
// Remap gray keys
|
||||||
if (kb_prefix&1) switch (scancode) {
|
if (KeyScancodePrefix&1) switch (scancode) {
|
||||||
case 0x7C: scancode=0x08; break; // PrintScreen
|
case 0x7C: scancode=0x08; break; // PrintScreen
|
||||||
case 0x4A: scancode=0x6A; break; // Numpad /
|
case 0x4A: scancode=0x6A; break; // Numpad /
|
||||||
case 0x5A: scancode=0x59; break; // Numpad Enter
|
case 0x5A: scancode=0x59; break; // Numpad Enter
|
||||||
@@ -151,38 +145,30 @@ void i86_kb_handler(ISR_stack_regs *r) {
|
|||||||
case 0x7A: scancode=0x67; break; // PageDown
|
case 0x7A: scancode=0x67; break; // PageDown
|
||||||
case 0x7D: scancode=0x68; break; // PageUp
|
case 0x7D: scancode=0x68; break; // PageUp
|
||||||
}
|
}
|
||||||
if ((kb_prefix&2) == 0) i86_kb_set_key(scancode, 1);
|
if ((KeyScancodePrefix&2) == 0) KeyboardSetKey(scancode, 1);
|
||||||
else i86_kb_set_key(scancode, 0);
|
else KeyboardSetKey(scancode, 0);
|
||||||
|
|
||||||
kb_prefix = 0; break;
|
KeyScancodePrefix = 0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alt+ctrl+del = reset
|
|
||||||
if (scancode==0x62) {
|
|
||||||
int ok=0;
|
|
||||||
if ((kb_modifier_status&4) || (kb_modifier_status&8)) ok++;
|
|
||||||
if ((kb_modifier_status&16) || (kb_modifier_status&32)) ok++;
|
|
||||||
if (ok==2) reboot();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
kb_key getkey()
|
KeyboardKey GetKey()
|
||||||
{
|
{
|
||||||
kb_key ret;
|
KeyboardKey ret;
|
||||||
|
|
||||||
kb_newdata = 0xFF;
|
KeyboardNewData = 0xFF;
|
||||||
while (kb_newdata==0xFF); // wait for keypress
|
while (KeyboardNewData==0xFF); // wait for keypress
|
||||||
|
|
||||||
ret.scancode = kb_newdata; // Send scancode for non-chars
|
ret.Scancode = KeyboardNewData; // Send scancode for non-chars
|
||||||
ret.status = kb_modifier_status; // Shift, ctrl... state
|
ret.ModifierStatus = KeyModifierStatus; // Shift, ctrl... state
|
||||||
ret.lights = kb_lights_status; // Num, caps.... state
|
ret.Lights = KeyLightsStatus; // Num, caps.... state
|
||||||
|
|
||||||
if ((ret.status & 1) || (ret.status & 2)) // Shift is on
|
if ((ret.ModifierStatus & 1) || (ret.ModifierStatus & 2)) // Shift is on
|
||||||
ret.character = kbdus_map_shift[ret.scancode];
|
ret.Character = KeyMapShift[ret.Scancode];
|
||||||
else ret.character = kbdus_map[ret.scancode]; // Shift is off
|
else ret.Character = KeyMap[ret.Scancode]; // Shift is off
|
||||||
|
|
||||||
return ret; // And send it.
|
return ret; // And send it.
|
||||||
}
|
}
|
||||||
@@ -209,7 +195,7 @@ kb_key getkey()
|
|||||||
250 | 500 | 750 | 1000
|
250 | 500 | 750 | 1000
|
||||||
|
|
||||||
***************************************/
|
***************************************/
|
||||||
void i86_kb_set_repeat(unsigned char rate, unsigned char delay)
|
void KeyboardSetRepeatRate(unsigned char rate, unsigned char delay)
|
||||||
{
|
{
|
||||||
if (rate>3 || delay>31) return;
|
if (rate>3 || delay>31) return;
|
||||||
|
|
||||||
@@ -230,7 +216,7 @@ void i86_kb_set_repeat(unsigned char rate, unsigned char delay)
|
|||||||
|(reserved) | lock | lock | lock |
|
|(reserved) | lock | lock | lock |
|
||||||
+-----------+-------+-------+--------+
|
+-----------+-------+-------+--------+
|
||||||
***************************************/
|
***************************************/
|
||||||
void i86_kb_set_LEDs(unsigned char status)
|
void KeyboardSetLEDs(unsigned char status)
|
||||||
{
|
{
|
||||||
while ((inportb (0x64)&2)!=0);
|
while ((inportb (0x64)&2)!=0);
|
||||||
outportb (0x60, 0xED);
|
outportb (0x60, 0xED);
|
||||||
@@ -247,7 +233,7 @@ void i86_kb_set_LEDs(unsigned char status)
|
|||||||
2 Set to scancode set 2
|
2 Set to scancode set 2
|
||||||
3 Set to scancode set 3
|
3 Set to scancode set 3
|
||||||
***************************************/
|
***************************************/
|
||||||
void i86_kb_set_scancodeset(unsigned char set)
|
void KeyboardSetScancodeSet(unsigned char set)
|
||||||
{
|
{
|
||||||
if (set>3) return;
|
if (set>3) return;
|
||||||
|
|
||||||
@@ -257,69 +243,64 @@ void i86_kb_set_scancodeset(unsigned char set)
|
|||||||
while ((inportb (0x64)&2)!=0);
|
while ((inportb (0x64)&2)!=0);
|
||||||
outportb (0x60, set);
|
outportb (0x60, set);
|
||||||
|
|
||||||
kb_scancode_set = set;
|
KeyboardScancodeSet = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char i86_kb_get_scancodeset() {
|
/*unsigned char i86_kb_get_scancodeset() {
|
||||||
return kb_scancode_set;
|
return KeyboardScancodeSet;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void i86_kb_waitin()
|
void KeyboardWaitInput()
|
||||||
{
|
{
|
||||||
int fail_safe=200000;
|
int fail_safe=200000;
|
||||||
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
|
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void i86_kb_waitout()
|
void KeyboardWaitOutput()
|
||||||
{
|
{
|
||||||
int fail_safe=200000;
|
int fail_safe=200000;
|
||||||
while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
|
while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i86_kb_install_partone()
|
void KeyboardInstallA()
|
||||||
{
|
{
|
||||||
i86_irq_install_handler(1, i86_kb_handler);// instali handler
|
KeyboardWaitInput(); outportb(0x60, 0xFF); // Reset kb
|
||||||
i86_kb_waitin(); outportb(0x60, 0xFF); // Reset kb
|
|
||||||
|
|
||||||
// Initialize variables
|
// Initialize variables
|
||||||
kb_newdata = 0;
|
KeyboardNewData = 0;
|
||||||
kb_modifier_status = 0;
|
KeyModifierStatus = 0;
|
||||||
kb_prefix = 0;
|
KeyScancodePrefix = 0;
|
||||||
kb_lights_status = 0;
|
KeyLightsStatus = 0;
|
||||||
kb_scancode_set = 0;
|
KeyboardScancodeSet = 0;
|
||||||
|
|
||||||
|
memset((void*)KeyArray, 0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int i86_kb_install_parttwo()
|
void KeyboardInstallB()
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
// Wait for BAT test results
|
// Wait for BAT test results
|
||||||
unsigned char temp;
|
unsigned char temp;
|
||||||
do temp = inportb(0x60);
|
do temp = inportb(0x60);
|
||||||
while (temp!=0xAA && temp!=0xFC);
|
while (temp!=0xAA && temp!=0xFC);
|
||||||
|
|
||||||
if (temp == 0xFC) ret = -1;
|
// Error
|
||||||
|
if (temp == 0xFC) return;
|
||||||
|
|
||||||
// Set new repeat rate
|
// Set new repeat rate
|
||||||
i86_kb_set_repeat(1, 11);
|
KeyboardSetRepeatRate(1, 11);
|
||||||
|
|
||||||
// Set scancode set 2
|
// Set scancode set 2
|
||||||
i86_kb_set_scancodeset(2); // Set new scancode set
|
KeyboardSetScancodeSet(2); // Set new scancode set
|
||||||
|
|
||||||
i86_kb_waitin();
|
KeyboardWaitInput();
|
||||||
outportb(0x64, 0x20); // Get "Command unsigned char"
|
outportb(0x64, 0x20); // Get "Command unsigned char"
|
||||||
|
|
||||||
do { temp = inportb(0x60);
|
do { temp = inportb(0x60);
|
||||||
} while (temp==0xFA || temp==0xAA);
|
} while (temp==0xFA || temp==0xAA);
|
||||||
|
|
||||||
temp &= 0xFF - (1<<6); // Set bit6 to 0: disable conversion
|
temp &= 0xFF - (1<<6); // Set bit6 to 0: disable conversion
|
||||||
i86_kb_waitin(); outportb(0x64, 0x60); // Function to write cmd unsigned char
|
KeyboardWaitInput(); outportb(0x64, 0x60); // Function to write cmd unsigned char
|
||||||
i86_kb_waitin(); outportb(0x60, temp); // Send it
|
KeyboardWaitInput(); outportb(0x60, temp); // Send it
|
||||||
memset((void*)kb_array, 0, 16);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
|
||||||
|
#define KB_KEY_LSHIFT 0x81 // 1000 0001
|
||||||
|
#define KB_KEY_RSHIFT 0X82 // 1000 0010
|
||||||
|
#define KB_KEY_LALT 0X84 // 1000 0100
|
||||||
|
#define KB_KEY_RALT 0x88 // 1000 1000
|
||||||
|
#define KB_KEY_LCTRL 0x90 // 1001 0000
|
||||||
|
#define KB_KEY_RCTRL 0xA0 // 1010 0000
|
||||||
|
#define KB_KEY_FSHIFT 0xC0 // 1100 0000
|
||||||
|
extern volatile unsigned char KeyModifierStatus;
|
||||||
|
|
||||||
|
#define KB_PREFIX_GRAY 0x01 // Gray
|
||||||
|
#define KB_PREFIX_BREAK 0x02 // Break code
|
||||||
|
#define KB_PREFIX_PAUSE 0x04 // Pause/break key
|
||||||
|
#define KB_PREFIX_PAUSE1 0x08 // Recieved first unsigned char from pause/break
|
||||||
|
extern volatile unsigned char KeyScancodePrefix;
|
||||||
|
|
||||||
|
#define KB_KEY_SCROLL 0xF1 // 1111 0001
|
||||||
|
#define KB_KEY_NUM 0xF2 // 1111 0010
|
||||||
|
#define KB_KEY_CAPS 0xF4 // 1111 0100
|
||||||
|
extern volatile unsigned char KeyLightsStatus;
|
||||||
|
|
||||||
|
extern unsigned char KeyboardScancodeSet;
|
||||||
|
|
||||||
|
enum KeyboardKeys {
|
||||||
|
KeyboardKeyPAUSE = 0x00,
|
||||||
|
KeyboardKeyF9 = 0x01,
|
||||||
|
KeyboardKeyF7 = 0x02,
|
||||||
|
KeyboardKeyF5 = 0X03,
|
||||||
|
KeyboardKeyF3 = 0x04,
|
||||||
|
KeyboardKeyF1 = 0x05,
|
||||||
|
KeyboardKeyF2 = 0x06,
|
||||||
|
KeyboardKeyF12 = 0x07,
|
||||||
|
KeyboardKeyPRINTSCRN = 0x08,
|
||||||
|
KeyboardKeyF10 = 0x09,
|
||||||
|
KeyboardKeyF8 = 0x0A,
|
||||||
|
KeyboardKeyF6 = 0x0B,
|
||||||
|
KeyboardKeyF4 = 0x0C,
|
||||||
|
KeyboardKeyTAB = 0x0D,
|
||||||
|
KeyboardKeyTILDA = 0x0E,
|
||||||
|
KeyboardKeyQ = 0x15,
|
||||||
|
KeyboardKey1 = 0x16,
|
||||||
|
KeyboardKeyZ = 0x1A,
|
||||||
|
KeyboardKeyS = 0x1B,
|
||||||
|
KeyboardKeyA = 0x1C,
|
||||||
|
KeyboardKeyW = 0x1D,
|
||||||
|
KeyboardKey2 = 0x1E,
|
||||||
|
KeyboardKeyLWIN = 0x1F,
|
||||||
|
KeyboardKeyC = 0x21,
|
||||||
|
KeyboardKeyX = 0x22,
|
||||||
|
KeyboardKeyD = 0x23,
|
||||||
|
KeyboardKeyE = 0x24,
|
||||||
|
KeyboardKey4 = 0x25,
|
||||||
|
KeyboardKey3 = 0x26,
|
||||||
|
KeyboardKeyRWIN = 0x27,
|
||||||
|
KeyboardKeySPACE = 0x29,
|
||||||
|
KeyboardKeyV = 0x2A,
|
||||||
|
KeyboardKeyF = 0x2B,
|
||||||
|
KeyboardKeyT = 0x2C,
|
||||||
|
KeyboardKeyR = 0x2D,
|
||||||
|
KeyboardKey5 = 0x2E,
|
||||||
|
KeyboardKeyMENU = 0x2F,
|
||||||
|
KeyboardKeyN = 0x31,
|
||||||
|
KeyboardKeyB = 0x32,
|
||||||
|
KeyboardKeyH = 0x33,
|
||||||
|
KeyboardKeyG = 0x34,
|
||||||
|
KeyboardKeyY = 0x35,
|
||||||
|
KeyboardKey6 = 0x36,
|
||||||
|
KeyboardKeyM = 0x3A,
|
||||||
|
KeyboardKeyJ = 0x3B,
|
||||||
|
KeyboardKeyU = 0x3C,
|
||||||
|
KeyboardKey7 = 0x3D,
|
||||||
|
KeyboardKey8 = 0x3E,
|
||||||
|
KeyboardKeyCOMMA = 0x41,
|
||||||
|
KeyboardKeyK = 0x42,
|
||||||
|
KeyboardKeyI = 0x43,
|
||||||
|
KeyboardKeyO = 0x44,
|
||||||
|
KeyboardKey0 = 0x45,
|
||||||
|
KeyboardKey9 = 0x46,
|
||||||
|
KeyboardKeyPERIOD = 0x49,
|
||||||
|
KeyboardKeySLASH = 0x4A,
|
||||||
|
KeyboardKeyL = 0x4B,
|
||||||
|
KeyboardKeySEMICOLON = 0x4C,
|
||||||
|
KeyboardKeyP = 0x4D,
|
||||||
|
KeyboardKeyDASH = 0x4E,
|
||||||
|
KeyboardKeyAPOSTROPHE = 0x52,
|
||||||
|
KeyboardKeyLBRACKET = 0x54,
|
||||||
|
KeyboardKeyEQUAL = 0x55,
|
||||||
|
KeyboardKeyNUMPAD_ENTER = 0x59,
|
||||||
|
KeyboardKeyENTER = 0x5A,
|
||||||
|
KeyboardKeyRBRACKET = 0x5B,
|
||||||
|
KeyboardKeyBACKSLASH = 0x5D,
|
||||||
|
KeyboardKeyEND = 0x5E,
|
||||||
|
KeyboardKeyLEFT = 0x5F,
|
||||||
|
KeyboardKeyHOME = 0x60,
|
||||||
|
KeyboardKeyINSERT = 0x61,
|
||||||
|
KeyboardKeyDELETE = 0x62,
|
||||||
|
KeyboardKeyDOWN = 0x63,
|
||||||
|
KeyboardKeyRIGHT = 0x64,
|
||||||
|
KeyboardKeyUP = 0x65,
|
||||||
|
KeyboardKeyBACKSPACE = 0x66,
|
||||||
|
KeyboardKeyPGDOWN = 0x67,
|
||||||
|
KeyboardKeyPGUP = 0x68,
|
||||||
|
KeyboardKeyNUMPAD_1 = 0x69,
|
||||||
|
KeyboardKeyNUMPAD_SLASH = 0x6A,
|
||||||
|
KeyboardKeyNUMPAD_4 = 0x6B,
|
||||||
|
KeyboardKeyNUMPAD_7 = 0x6C,
|
||||||
|
KeyboardKeyNUMPAD_0 = 0x70,
|
||||||
|
KeyboardKeyNUMPAD_COLON = 0x71,
|
||||||
|
KeyboardKeyNUMPAD_2 = 0x72,
|
||||||
|
KeyboardKeyNUMPAD_5 = 0x73,
|
||||||
|
KeyboardKeyNUMPAD_6 = 0x74,
|
||||||
|
KeyboardKeyNUMPAD_8 = 0x75,
|
||||||
|
KeyboardKeyESC = 0x76,
|
||||||
|
KeyboardKeyF11 = 0x78,
|
||||||
|
KeyboardKeyNUMPAD_PLUS = 0x79,
|
||||||
|
KeyboardKeyNUMPAD_3 = 0x7A,
|
||||||
|
KeyboardKeyNUMPAD_MINUS = 0x7B,
|
||||||
|
KeyboardKeyNUMPAD_ASTERISK = 0x7C,
|
||||||
|
KeyboardKeyNUMPAD_9 = 0x7D
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char status;
|
||||||
|
unsigned char lights;
|
||||||
|
unsigned char scancode;
|
||||||
|
unsigned char character;
|
||||||
|
} kb_key;
|
||||||
|
|
||||||
|
|
||||||
|
extern char getch();
|
||||||
|
extern kb_key get_key();
|
||||||
|
extern char scancode_to_ascii(unsigned char scancode);
|
||||||
|
extern unsigned char get_key_status(unsigned char scancode);
|
||||||
|
extern void kb_set_repeat(float rate, int delay);
|
||||||
|
extern void kb_set_LEDs(unsigned char status);
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
|
||||||
|
#define KB_KEY_LSHIFT 0x81 // 1000 0001
|
||||||
|
#define KB_KEY_RSHIFT 0X82 // 1000 0010
|
||||||
|
#define KB_KEY_LALT 0X84 // 1000 0100
|
||||||
|
#define KB_KEY_RALT 0x88 // 1000 1000
|
||||||
|
#define KB_KEY_LCTRL 0x90 // 1001 0000
|
||||||
|
#define KB_KEY_RCTRL 0xA0 // 1010 0000
|
||||||
|
#define KB_KEY_FSHIFT 0xC0 // 1100 0000
|
||||||
|
extern volatile unsigned char KeyModifierStatus;
|
||||||
|
|
||||||
|
#define KB_PREFIX_GRAY 0x01 // Gray
|
||||||
|
#define KB_PREFIX_BREAK 0x02 // Break code
|
||||||
|
#define KB_PREFIX_PAUSE 0x04 // Pause/break key
|
||||||
|
#define KB_PREFIX_PAUSE1 0x08 // Recieved first unsigned char from pause/break
|
||||||
|
extern volatile unsigned char KeyScancodePrefix;
|
||||||
|
|
||||||
|
#define KB_KEY_SCROLL 0xF1 // 1111 0001
|
||||||
|
#define KB_KEY_NUM 0xF2 // 1111 0010
|
||||||
|
#define KB_KEY_CAPS 0xF4 // 1111 0100
|
||||||
|
extern volatile unsigned char KeyLightsStatus;
|
||||||
|
|
||||||
|
extern unsigned char KeyboardScancodeSet;
|
||||||
|
|
||||||
|
enum KB_KEYS {
|
||||||
|
KB_KEY_PAUSE = 0x00,
|
||||||
|
KB_KEY_F9 = 0x01,
|
||||||
|
KB_KEY_F7 = 0x02,
|
||||||
|
KB_KEY_F5 = 0X03,
|
||||||
|
KB_KEY_F3 = 0x04,
|
||||||
|
KB_KEY_F1 = 0x05,
|
||||||
|
KB_KEY_F2 = 0x06,
|
||||||
|
KB_KEY_F12 = 0x07,
|
||||||
|
KB_KEY_PRINTSCRN = 0x08,
|
||||||
|
KB_KEY_F10 = 0x09,
|
||||||
|
KB_KEY_F8 = 0x0A,
|
||||||
|
KB_KEY_F6 = 0x0B,
|
||||||
|
KB_KEY_F4 = 0x0C,
|
||||||
|
KB_KEY_TAB = 0x0D,
|
||||||
|
KB_KEY_TILDA = 0x0E,
|
||||||
|
KB_KEY_Q = 0x15,
|
||||||
|
KB_KEY_1 = 0x16,
|
||||||
|
KB_KEY_Z = 0x1A,
|
||||||
|
KB_KEY_S = 0x1B,
|
||||||
|
KB_KEY_A = 0x1C,
|
||||||
|
KB_KEY_W = 0x1D,
|
||||||
|
KB_KEY_2 = 0x1E,
|
||||||
|
KB_KEY_LWIN = 0x1F,
|
||||||
|
KB_KEY_C = 0x21,
|
||||||
|
KB_KEY_X = 0x22,
|
||||||
|
KB_KEY_D = 0x23,
|
||||||
|
KB_KEY_E = 0x24,
|
||||||
|
KB_KEY_4 = 0x25,
|
||||||
|
KB_KEY_3 = 0x26,
|
||||||
|
KB_KEY_RWIN = 0x27,
|
||||||
|
KB_KEY_SPACE = 0x29,
|
||||||
|
KB_KEY_V = 0x2A,
|
||||||
|
KB_KEY_F = 0x2B,
|
||||||
|
KB_KEY_T = 0x2C,
|
||||||
|
KB_KEY_R = 0x2D,
|
||||||
|
KB_KEY_5 = 0x2E,
|
||||||
|
KB_KEY_MENU = 0x2F,
|
||||||
|
KB_KEY_N = 0x31,
|
||||||
|
KB_KEY_B = 0x32,
|
||||||
|
KB_KEY_H = 0x33,
|
||||||
|
KB_KEY_G = 0x34,
|
||||||
|
KB_KEY_Y = 0x35,
|
||||||
|
KB_KEY_6 = 0x36,
|
||||||
|
KB_KEY_M = 0x3A,
|
||||||
|
KB_KEY_J = 0x3B,
|
||||||
|
KB_KEY_U = 0x3C,
|
||||||
|
KB_KEY_7 = 0x3D,
|
||||||
|
KB_KEY_8 = 0x3E,
|
||||||
|
KB_KEY_COMMA = 0x41,
|
||||||
|
KB_KEY_K = 0x42,
|
||||||
|
KB_KEY_I = 0x43,
|
||||||
|
KB_KEY_O = 0x44,
|
||||||
|
KB_KEY_0 = 0x45,
|
||||||
|
KB_KEY_9 = 0x46,
|
||||||
|
KB_KEY_PERIOD = 0x49,
|
||||||
|
KB_KEY_SLASH = 0x4A,
|
||||||
|
KB_KEY_L = 0x4B,
|
||||||
|
KB_KEY_SEMICOLON = 0x4C,
|
||||||
|
KB_KEY_P = 0x4D,
|
||||||
|
KB_KEY_DASH = 0x4E,
|
||||||
|
KB_KEY_APOSTROPHE = 0x52,
|
||||||
|
KB_KEY_LBRACKET = 0x54,
|
||||||
|
KB_KEY_EQUAL = 0x55,
|
||||||
|
KB_KEY_NUMPAD_ENTER = 0x59,
|
||||||
|
KB_KEY_ENTER = 0x5A,
|
||||||
|
KB_KEY_RBRACKET = 0x5B,
|
||||||
|
KB_KEY_BACKSLASH = 0x5D,
|
||||||
|
KB_KEY_END = 0x5E,
|
||||||
|
KB_KEY_LEFT = 0x5F,
|
||||||
|
KB_KEY_HOME = 0x60,
|
||||||
|
KB_KEY_INSERT = 0x61,
|
||||||
|
KB_KEY_DELETE = 0x62,
|
||||||
|
KB_KEY_DOWN = 0x63,
|
||||||
|
KB_KEY_RIGHT = 0x64,
|
||||||
|
KB_KEY_UP = 0x65,
|
||||||
|
KB_KEY_BACKSPACE = 0x66,
|
||||||
|
KB_KEY_PGDOWN = 0x67,
|
||||||
|
KB_KEY_PGUP = 0x68,
|
||||||
|
KB_KEY_NUMPAD_1 = 0x69,
|
||||||
|
KB_KEY_NUMPAD_SLASH = 0x6A,
|
||||||
|
KB_KEY_NUMPAD_4 = 0x6B,
|
||||||
|
KB_KEY_NUMPAD_7 = 0x6C,
|
||||||
|
KB_KEY_NUMPAD_0 = 0x70,
|
||||||
|
KB_KEY_NUMPAD_COLON = 0x71,
|
||||||
|
KB_KEY_NUMPAD_2 = 0x72,
|
||||||
|
KB_KEY_NUMPAD_5 = 0x73,
|
||||||
|
KB_KEY_NUMPAD_6 = 0x74,
|
||||||
|
KB_KEY_NUMPAD_8 = 0x75,
|
||||||
|
KB_KEY_ESC = 0x76,
|
||||||
|
KB_KEY_F11 = 0x78,
|
||||||
|
KB_KEY_NUMPAD_PLUS = 0x79,
|
||||||
|
KB_KEY_NUMPAD_3 = 0x7A,
|
||||||
|
KB_KEY_NUMPAD_MINUS = 0x7B,
|
||||||
|
KB_KEY_NUMPAD_ASTERISK = 0x7C,
|
||||||
|
KB_KEY_NUMPAD_9 = 0x7D
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char status;
|
||||||
|
unsigned char lights;
|
||||||
|
unsigned char scancode;
|
||||||
|
unsigned char character;
|
||||||
|
} kb_key;
|
||||||
|
|
||||||
|
|
||||||
|
extern char getch();
|
||||||
|
extern kb_key get_key();
|
||||||
|
extern char scancode_to_ascii(unsigned char scancode);
|
||||||
|
extern unsigned char get_key_status(unsigned char scancode);
|
||||||
|
extern void kb_set_repeat(float rate, int delay);
|
||||||
|
extern void kb_set_LEDs(unsigned char status);
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
@echo off
|
||||||
|
set nasm_path=C:\nasm
|
||||||
|
set djgpp_path=C:\mingw\bin
|
||||||
|
|
||||||
|
goto this
|
||||||
|
|
||||||
|
:error
|
||||||
|
@echo.
|
||||||
|
@echo There have been build errors. Building halted.
|
||||||
|
@pause
|
||||||
|
exit
|
||||||
|
|
||||||
|
:this
|
||||||
|
@echo Building Drivers...
|
||||||
|
set objpath=..\objects\drivers
|
||||||
|
set incpath=../include
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o drivers.o drivers.c
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o BSOD.o BSOD.c
|
||||||
|
|
||||||
|
if not exist drivers.o goto error
|
||||||
|
if not exist BSOD.o goto error
|
||||||
|
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
|
||||||
|
:clock
|
||||||
|
set objpath=..\..\objects\drivers
|
||||||
|
set incpath=../../include
|
||||||
|
|
||||||
|
cd clock
|
||||||
|
@echo * Compiling internal clock...
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o pit.o pit.c
|
||||||
|
if not exist pit.o goto error
|
||||||
|
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
|
||||||
|
cd..
|
||||||
|
|
||||||
|
|
||||||
|
:floppy
|
||||||
|
cd floppy
|
||||||
|
@echo * Compiling floppy driver...
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o dma.o dma.c
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o floppy.o floppy.c
|
||||||
|
if not exist dma.o goto error
|
||||||
|
if not exist floppy.o goto error
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
|
||||||
|
cd..
|
||||||
|
|
||||||
|
:filesys
|
||||||
|
cd filesys
|
||||||
|
@echo * Compiling file systems...
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o fat.o fat.c
|
||||||
|
rem %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o floppy.o floppy.c
|
||||||
|
if not exist fat.o goto error
|
||||||
|
rem if not exist floppy.o goto error
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
|
||||||
|
cd..
|
||||||
|
|
||||||
|
:keyboard
|
||||||
|
cd keyboard
|
||||||
|
@echo * Compiling keyboard driver...
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o keyboard.o keyboard.c
|
||||||
|
if not exist keyboard.o goto error
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
|
||||||
|
cd..
|
||||||
|
|
||||||
|
|
||||||
|
:cpu
|
||||||
|
cd cpu
|
||||||
|
@echo * Compiling Central Processing Unit (CPU) modules...
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o cpu.o cpu.c
|
||||||
|
if not exist cpu.o goto error
|
||||||
|
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
|
||||||
|
set objpath=..\..\..\objects\drivers
|
||||||
|
set incpath=../../../include
|
||||||
|
|
||||||
|
:gdt
|
||||||
|
@echo + Global Descriptor Table
|
||||||
|
cd gdt
|
||||||
|
|
||||||
|
rem Assembly File:
|
||||||
|
%nasm_path%\nasm.exe -f aout -o gdt_asm.o gdt.asm
|
||||||
|
if not exist gdt_asm.o goto error
|
||||||
|
|
||||||
|
rem C File:
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o gdt.o gdt.c
|
||||||
|
if not exist gdt.o goto error
|
||||||
|
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
cd..
|
||||||
|
|
||||||
|
:idt
|
||||||
|
@echo + Interrupt Descriptor Table
|
||||||
|
cd idt
|
||||||
|
|
||||||
|
rem Assembly File:
|
||||||
|
%nasm_path%\nasm.exe -f aout -o idt_asm.o idt.asm
|
||||||
|
if not exist idt_asm.o goto error
|
||||||
|
|
||||||
|
rem C File:
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o idt.o idt.c
|
||||||
|
if not exist idt.o goto error
|
||||||
|
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
cd..
|
||||||
|
|
||||||
|
:irq
|
||||||
|
@echo + Interrupt Requests
|
||||||
|
cd irq
|
||||||
|
|
||||||
|
rem IRQ Assembly File:
|
||||||
|
%nasm_path%\nasm.exe -f aout -o irq_asm.o irq.asm
|
||||||
|
if not exist irq_asm.o goto error
|
||||||
|
|
||||||
|
rem IRQ C File:
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o irq.o irq.c
|
||||||
|
if not exist irq.o goto error
|
||||||
|
|
||||||
|
@echo + Programmable Interrupt Controller
|
||||||
|
rem PIC C File:
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o pic.o pic.c
|
||||||
|
if not exist pic.o goto error
|
||||||
|
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
cd..
|
||||||
|
|
||||||
|
:isrs
|
||||||
|
@echo + Interrupt Service Routines
|
||||||
|
cd isrs
|
||||||
|
|
||||||
|
rem Assembly File:
|
||||||
|
%nasm_path%\nasm.exe -f aout -o isrs_asm.o isrs.asm
|
||||||
|
if not exist isrs_asm.o goto error
|
||||||
|
|
||||||
|
rem C File:
|
||||||
|
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o isrs.o isrs.c
|
||||||
|
if not exist isrs.o goto error
|
||||||
|
|
||||||
|
xcopy /Y *.o %objpath% >nul
|
||||||
|
del *.o
|
||||||
|
cd..
|
||||||
|
|
||||||
|
|
||||||
|
cd..
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
.:
|
||||||
|
compile.bat drivers include loader.asm makeall.bat memory shell
|
||||||
|
debug filelist.txt lib main.c makeallh.bat objects video
|
||||||
|
|
||||||
|
./debug:
|
||||||
|
BIOS-bochs-latest bochs_config.bxrc ctaos.img OSDev.log VGABIOS-lgpl-latest
|
||||||
|
|
||||||
|
./drivers:
|
||||||
|
BSOD.c compile.bat drivers.c filesys keyboard makeall.bat.bak
|
||||||
|
clock cpu drivers.h floppy makeall.bat
|
||||||
|
|
||||||
|
./drivers/clock:
|
||||||
|
clock.h pit.c
|
||||||
|
|
||||||
|
./drivers/cpu:
|
||||||
|
compile.bat cpu.c cpu.h gdt idt irq isrs
|
||||||
|
|
||||||
|
./drivers/cpu/gdt:
|
||||||
|
gdt.asm gdt.c gdt.h
|
||||||
|
|
||||||
|
./drivers/cpu/idt:
|
||||||
|
idt.asm idt.c idt.h
|
||||||
|
|
||||||
|
./drivers/cpu/irq:
|
||||||
|
irq.asm irq.c irq.h pic.c pic.h
|
||||||
|
|
||||||
|
./drivers/cpu/isrs:
|
||||||
|
isrs.asm isrs.c isrs.h
|
||||||
|
|
||||||
|
./drivers/filesys:
|
||||||
|
fat.c fat.h vfs.c vfs.h
|
||||||
|
|
||||||
|
./drivers/floppy:
|
||||||
|
dma.c dma.h floppy.c floppy.h storage.h
|
||||||
|
|
||||||
|
./drivers/keyboard:
|
||||||
|
compile.bat keyboard.deprecated.h key_list.txt
|
||||||
|
keyboard.c keyboard.h.deprecated
|
||||||
|
|
||||||
|
./include:
|
||||||
|
bootinfo.h crtdefs.h cstring hal.h size_t.h stdlib.h system.h
|
||||||
|
cctype cstdarg ctype.h _null.h stdarg.h string.h time.h
|
||||||
|
conio.h cstdint drivers regs.h stdint.h sys va_list.h
|
||||||
|
|
||||||
|
./include/drivers:
|
||||||
|
floppy.h keyboard.h
|
||||||
|
|
||||||
|
./include/sys:
|
||||||
|
declarat.h
|
||||||
|
|
||||||
|
./lib:
|
||||||
|
compile.bat conio.c ctype.c stdlib.c string.c system.c time.c
|
||||||
|
|
||||||
|
./memory:
|
||||||
|
compile.bat lib mmngr.asm mmngr_ph.c mmngr_ph.h mmngr_vi.c mmngr_vi.h
|
||||||
|
|
||||||
|
./memory/lib:
|
||||||
|
pde.c pde.h pte.c pte.h
|
||||||
|
|
||||||
|
./objects:
|
||||||
|
compile.bat drivers main.o mmngr_ph.o release string.o video
|
||||||
|
conio.o link.ld mmngr_de.o mmngr_te.o shell.o system.o
|
||||||
|
ctype.o loader.o mmngr.o mmngr_vi.o stdlib.o time.o
|
||||||
|
|
||||||
|
./objects/drivers:
|
||||||
|
BSOD.o drivers.o floppy.o idt_asm.o irq.o keyboard.o
|
||||||
|
cpu.o fat12.o gdt_asm.o idt.o isrs_asm.o pic.o
|
||||||
|
dma.o fat.o gdt.o irq_asm.o isrs.o pit.o
|
||||||
|
|
||||||
|
./objects/release:
|
||||||
|
|
||||||
|
./objects/video:
|
||||||
|
vga03h.o
|
||||||
|
|
||||||
|
./shell:
|
||||||
|
apps.h compile.bat shell.c
|
||||||
|
|
||||||
|
./video:
|
||||||
|
color compile.bat vga03h.c vga03h.h vga.h
|
||||||
|
|
||||||
|
./video/color:
|
||||||
|
color.c color.h
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/***** cmos.c ********************************************************
|
|
||||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
|
||||||
* *
|
|
||||||
* CMOS I/O Routines *
|
|
||||||
* ================= *
|
|
||||||
* *
|
|
||||||
* ! IMPORTANT NOTE ! Close interrupts before any CMOS operation *
|
|
||||||
************************************************************ cta os */
|
|
||||||
|
|
||||||
#include <system.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "cmos.h"
|
|
||||||
|
|
||||||
/*****************************************************************
|
|
||||||
* !!!!!!!!!! IMPORTANT NOTE !!!!!!!!!! *
|
|
||||||
* You should close interrupts before any CMOS operation. *
|
|
||||||
*****************************************************************/
|
|
||||||
inline unsigned char i86_cmos_read (unsigned char address)
|
|
||||||
{
|
|
||||||
outportb(0x70, address); iowait();
|
|
||||||
return inportb(0x71);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void i86_cmos_write (unsigned char address, unsigned char val)
|
|
||||||
{
|
|
||||||
outportb(0x70, address); iowait();
|
|
||||||
outportb(0x71, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void i86_cmos_write_clock (const TIME* time)
|
|
||||||
{
|
|
||||||
unsigned char BCD = ((i86_cmos_read(0x0b)&4)==0) ? 1 : 0;
|
|
||||||
unsigned char ampm = ((i86_cmos_read(0x0b)&2)==0) ? 1 : 0;
|
|
||||||
|
|
||||||
i86_cmos_write (0, (BCD) ? (time->second%10) | (time->second/10*16) : time->second); // Seconds
|
|
||||||
i86_cmos_write (2, (BCD) ? (time->minute%10) | (time->minute/10*16) : time->minute); // Minutes
|
|
||||||
|
|
||||||
if (ampm && time->hour > 12) // Hours
|
|
||||||
i86_cmos_write (4, (BCD) ? (((time->hour - 12) % 10) | ((time->hour - 12)/10*16) | 0x80) : (time->hour | 0x80) );
|
|
||||||
|
|
||||||
else if (ampm && time->hour == 0) // Midnight convention: 12 PM = 00:00
|
|
||||||
i86_cmos_write (4, (BCD) ? 0x92 : 0x8C);
|
|
||||||
|
|
||||||
else i86_cmos_write (4, (BCD) ? (time->hour%10) | (time->hour/10*16) : time->hour); // 24h / AM
|
|
||||||
|
|
||||||
i86_cmos_write (6, (BCD) ? (time->weekday%10) | (time->weekday/10*16) : time->weekday); // Weekday
|
|
||||||
i86_cmos_write (7, (BCD) ? (time->day%10) | (time->day/10*16) : time->day); // Day
|
|
||||||
i86_cmos_write (8, (BCD) ? (time->month%10) | (time->month/10*16) : time->month); // Month
|
|
||||||
i86_cmos_write (9, (BCD) ? (time->year%10) | (time->year/10*16) : time->year); // Year
|
|
||||||
i86_cmos_write (0x32, (BCD) ? (time->century%10) | (time->century/10*16) : time->century); // Century
|
|
||||||
}
|
|
||||||
|
|
||||||
void i86_cmos_read_clock(TIME* tim)
|
|
||||||
{
|
|
||||||
unsigned char BCD = ((i86_cmos_read(0x0b)&4)==0) ? 1 : 0;
|
|
||||||
unsigned char am_pm = ((i86_cmos_read(0x0b)&2)==0) ? 1 : 0;
|
|
||||||
|
|
||||||
tim->second = (BCD) ? (i86_cmos_read(0x00)%16) + 10*(i86_cmos_read(0x00)/16): i86_cmos_read(0x00);
|
|
||||||
tim->minute = (BCD) ? (i86_cmos_read(0x02)%16) + 10*(i86_cmos_read(0x02)/16): i86_cmos_read(0x02);
|
|
||||||
|
|
||||||
// Time is PM
|
|
||||||
if (am_pm && i86_cmos_read(0x04)&80) {
|
|
||||||
tim->hour = (BCD) ? ((i86_cmos_read(0x04)-0x80)%16) + 10*((i86_cmos_read(0x04)-0x80)/16): i86_cmos_read(0x04)-0x80;
|
|
||||||
tim->hour += 12;
|
|
||||||
}
|
|
||||||
// 24Hour format, or AM
|
|
||||||
else tim->hour = (BCD) ? (i86_cmos_read(0x04)%16) + 10*(i86_cmos_read(0x04)/16): i86_cmos_read(0x04);
|
|
||||||
|
|
||||||
tim->weekday = (BCD) ? (i86_cmos_read(0x06)%16) + 10*(i86_cmos_read(0x06)/16): i86_cmos_read(0x06);
|
|
||||||
tim->day = (BCD) ? (i86_cmos_read(0x07)%16) + 10*(i86_cmos_read(0x07)/16): i86_cmos_read(0x07);
|
|
||||||
tim->month = (BCD) ? (i86_cmos_read(0x08)%16) + 10*(i86_cmos_read(0x08)/16): i86_cmos_read(0x08);
|
|
||||||
tim->year = (BCD) ? (i86_cmos_read(0x09)%16) + 10*(i86_cmos_read(0x09)/16): i86_cmos_read(0x09);
|
|
||||||
tim->century = (BCD) ? (i86_cmos_read(0x32)%16) + 10*(i86_cmos_read(0x32)/16): i86_cmos_read(0x32);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char i86_cmos_read_floppy_drives ()
|
|
||||||
{
|
|
||||||
outportb (0x70, 0x10);
|
|
||||||
return inportb(0x71);
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/***** cmos.h ********************************************************
|
|
||||||
* (c) 2010 CTA Systems Inc. All rights reserved. *
|
|
||||||
* *
|
|
||||||
* CMOS I/O Routines *
|
|
||||||
* ================= *
|
|
||||||
* *
|
|
||||||
* ! IMPORTANT NOTE ! Close interrupts before any CMOS operation *
|
|
||||||
************************************************************ cta os */
|
|
||||||
|
|
||||||
#ifndef __CMOS_H
|
|
||||||
#define __CMOS_H
|
|
||||||
|
|
||||||
extern void i86_cmos_write_clock (const TIME* time);
|
|
||||||
extern void i86_cmos_read_clock (TIME *tim);
|
|
||||||
extern unsigned char i86_cmos_read_floppy_drives ();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cmos.o cmos.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#include <system.h>
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "../gdt/gdt.h"
|
|
||||||
#include "../idt/idt.h"
|
|
||||||
#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
|
|
||||||
|
|
||||||
// initializes cpu resources
|
|
||||||
void i86_cpu_initialize()
|
|
||||||
{
|
|
||||||
// initialize processor tables
|
|
||||||
i86_gdt_install();
|
|
||||||
i86_idt_install();
|
|
||||||
}
|
|
||||||
|
|
||||||
void i86_cpu_shutdown()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
char* i86_cpu_get_vender()
|
|
||||||
{
|
|
||||||
dword unused;
|
|
||||||
dword static arr[3];
|
|
||||||
|
|
||||||
cpuid(0, unused, arr[0], arr[2], arr[1]);
|
|
||||||
|
|
||||||
return (char*) arr;
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#ifndef _CPU_H_INCLUDED
|
|
||||||
#define _CPU_H_INCLUDED
|
|
||||||
//****************************************************************************
|
|
||||||
//**
|
|
||||||
//** cpu.h
|
|
||||||
//**
|
|
||||||
//** This is the processor interface. Everything outside of this module
|
|
||||||
//** must use this interface when working on processor data.
|
|
||||||
//**
|
|
||||||
//** A processor is a module that manages the very basic data structures
|
|
||||||
//** and data within the system. The processor interface provides the interface
|
|
||||||
//** for managing processors, processor cores, accessing processor structures,
|
|
||||||
//** and more
|
|
||||||
//**
|
|
||||||
//****************************************************************************
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <regs.h>
|
|
||||||
|
|
||||||
//! initialize the processors
|
|
||||||
extern void i86_cpu_initialize ();
|
|
||||||
|
|
||||||
//! shutdown the processors
|
|
||||||
extern void i86_cpu_shutdown ();
|
|
||||||
|
|
||||||
//! get cpu vender
|
|
||||||
extern char* i86_cpu_get_vender ();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
/***** dma.c *********************************************************
|
|
||||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
|
||||||
* *
|
|
||||||
* Direct Memory Access (DMA) Routines *
|
|
||||||
* =================================== *
|
|
||||||
* *
|
|
||||||
************************************************************ cta os */
|
|
||||||
|
|
||||||
#include "dma.h"
|
|
||||||
#include <system.h>
|
|
||||||
|
|
||||||
enum DMA0_IO {
|
|
||||||
DMA0_STATUS_REG = 0x08,
|
|
||||||
DMA0_COMMAND_REG = 0x08,
|
|
||||||
DMA0_REQUEST_REG = 0x09,
|
|
||||||
DMA0_CHANMASK_REG = 0x0a,
|
|
||||||
DMA0_MODE_REG = 0x0b,
|
|
||||||
DMA0_CLEARBYTE_FLIPFLOP_REG = 0x0c,
|
|
||||||
DMA0_TEMP_REG = 0x0d,
|
|
||||||
DMA0_MASTER_CLEAR_REG = 0x0d,
|
|
||||||
DMA0_CLEAR_MASK_REG = 0x0e,
|
|
||||||
DMA0_MASK_REG = 0x0f
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DMA1_IO {
|
|
||||||
DMA1_STATUS_REG = 0xd0,
|
|
||||||
DMA1_COMMAND_REG = 0xd0,
|
|
||||||
DMA1_REQUEST_REG = 0xd2,
|
|
||||||
DMA1_CHANMASK_REG = 0xd4,
|
|
||||||
DMA1_MODE_REG = 0xd6,
|
|
||||||
DMA1_CLEARBYTE_FLIPFLOP_REG = 0xd8,
|
|
||||||
DMA1_INTER_REG = 0xda,
|
|
||||||
DMA1_UNMASK_ALL_REG = 0xdc,
|
|
||||||
DMA1_MASK_REG = 0xde
|
|
||||||
};
|
|
||||||
|
|
||||||
void i86_dma_set_address(unsigned short channel, unsigned char low, unsigned char high)
|
|
||||||
{
|
|
||||||
if (channel > 7) return; // Ignore if channel > 7
|
|
||||||
|
|
||||||
// Calculate port
|
|
||||||
unsigned short port = (channel >= 4) ? 4*(channel - 4) + 0xc0 : 2*channel;
|
|
||||||
|
|
||||||
// Set address
|
|
||||||
outportb (port, low);
|
|
||||||
outportb (port, high);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_set_count (unsigned short channel, unsigned char low, unsigned char high)
|
|
||||||
{
|
|
||||||
if (channel > 7) return; // Ignore if channel > 7
|
|
||||||
|
|
||||||
// Calculate port
|
|
||||||
unsigned short port = (channel >= 4) ? 4*(channel - 4) + 0xc2
|
|
||||||
: (2*channel) + 1;
|
|
||||||
|
|
||||||
// Set count
|
|
||||||
outportb (port, low);
|
|
||||||
outportb (port, high);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_set_external_page_registers (unsigned char channel, unsigned char val)
|
|
||||||
{
|
|
||||||
unsigned short port = 0;
|
|
||||||
|
|
||||||
switch (channel) {
|
|
||||||
case 1: port = 0x83; break;
|
|
||||||
case 2: port = 0x81; break;
|
|
||||||
case 3: port = 0x82; break;
|
|
||||||
// <- nothing should ever write to chan 4
|
|
||||||
case 5: port = 0x89; break;
|
|
||||||
case 6: port = 0x87; break;
|
|
||||||
case 7: port = 0x88; break;
|
|
||||||
default: if (channel == 4 || channel > 14) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
outportb(port, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_mask_channel (unsigned char channel)
|
|
||||||
{
|
|
||||||
if (channel <= 4) outportb (DMA0_CHANMASK_REG, (1<< (channel -1)));
|
|
||||||
else outportb (DMA1_CHANMASK_REG, (1<< (channel -5)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_unmask_channel (unsigned char channel)
|
|
||||||
{
|
|
||||||
if (channel <= 4) outportb (DMA0_CHANMASK_REG, channel);
|
|
||||||
else outportb (DMA1_CHANMASK_REG, channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_unmask_all()
|
|
||||||
{
|
|
||||||
outportb (DMA1_UNMASK_ALL_REG, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_reset_flipflop (unsigned char dma)
|
|
||||||
{
|
|
||||||
switch (dma) {
|
|
||||||
case 0: outportb (DMA0_CLEARBYTE_FLIPFLOP_REG, 0xff);
|
|
||||||
case 1: outportb (DMA1_CLEARBYTE_FLIPFLOP_REG, 0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void i86_dma_reset ()
|
|
||||||
{
|
|
||||||
outportb (DMA0_TEMP_REG, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_set_mode(unsigned char channel, unsigned char mode)
|
|
||||||
{
|
|
||||||
unsigned char dma = (channel < 4) ? 0:1;
|
|
||||||
unsigned char chan = (dma == 0) ? channel : channel-4;
|
|
||||||
|
|
||||||
i86_dma_mask_channel (channel);
|
|
||||||
outportb ((channel < 4) ? DMA0_MODE_REG : DMA1_MODE_REG, chan | mode);
|
|
||||||
i86_dma_unmask_all ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_set_read (unsigned char channel)
|
|
||||||
{
|
|
||||||
i86_dma_set_mode (channel, DMA_MODE_READ_TRANSFER | DMA_MODE_TRANSFER_SINGLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_dma_set_write (unsigned char channel)
|
|
||||||
{
|
|
||||||
i86_dma_set_mode (channel, DMA_MODE_WRITE_TRANSFER | DMA_MODE_TRANSFER_SINGLE);
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/***** dma.h *********************************************************
|
|
||||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
|
||||||
* *
|
|
||||||
* Direct Memory Access (DMA) Routines *
|
|
||||||
* =================================== *
|
|
||||||
* *
|
|
||||||
************************************************************ cta os */
|
|
||||||
|
|
||||||
#ifndef __DMA__H__
|
|
||||||
#define __DMA__H__
|
|
||||||
|
|
||||||
enum DMA_MODE_REG_MASK {
|
|
||||||
DMA_MODE_MASK_SEL = 3,
|
|
||||||
|
|
||||||
DMA_MODE_MASK_TRA = 0xc,
|
|
||||||
DMA_MODE_SELF_TEST = 0,
|
|
||||||
DMA_MODE_READ_TRANSFER = 4,
|
|
||||||
DMA_MODE_WRITE_TRANSFER = 8,
|
|
||||||
|
|
||||||
DMA_MODE_MASK_AUTO = 0x10,
|
|
||||||
DMA_MODE_MASK_IDEC = 0x20,
|
|
||||||
|
|
||||||
DMA_MODE_MASK = 0xc0,
|
|
||||||
DMA_MODE_TRANSFER_ON_DEMAND = 0,
|
|
||||||
DMA_MODE_TRANSFER_SINGLE = 0x40,
|
|
||||||
DMA_MODE_TRANSFER_BLOCK = 0x80,
|
|
||||||
DMA_MODE_TRANSFER_CASCADE = 0xC0
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void i86_dma_set_address(unsigned short channel, unsigned char low, unsigned char high);
|
|
||||||
extern void i86_dma_set_count (unsigned short channel, unsigned char low, unsigned char high);
|
|
||||||
extern void i86_dma_set_external_page_registers (unsigned char channel, unsigned char val);
|
|
||||||
extern void i86_dma_mask_channel (unsigned char channel);
|
|
||||||
extern void i86_dma_unmask_channel (unsigned char channel);
|
|
||||||
extern void i86_dma_unmask_all();
|
|
||||||
extern void i86_dma_reset_flipflop (unsigned char dma);
|
|
||||||
extern void i86_dma_reset ();
|
|
||||||
extern void i86_dma_set_mode(unsigned char channel, unsigned char mode);
|
|
||||||
extern void i86_dma_set_read (unsigned char channel);
|
|
||||||
extern void i86_dma_set_write (unsigned char channel);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/floppy.o floppy.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,356 +0,0 @@
|
|||||||
/***** floppy.c ******************************************************
|
|
||||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
|
||||||
* *
|
|
||||||
* Floppy Drive I/O Routines *
|
|
||||||
* ========================= *
|
|
||||||
* *
|
|
||||||
************************************************************ cta os */
|
|
||||||
#include "../irq/irq.h"
|
|
||||||
#include "../dma/dma.h"
|
|
||||||
#include <system.h>
|
|
||||||
#include <conio.h>
|
|
||||||
|
|
||||||
|
|
||||||
// Used ports:
|
|
||||||
// ***********
|
|
||||||
// Digital Output Register (DOR): 0x3f2
|
|
||||||
// Main Status Register (MSR): 0x3f4
|
|
||||||
// Data Register (FIFO): 0x3f5
|
|
||||||
// Configuration Control Register (CTRL): 0x3f7
|
|
||||||
|
|
||||||
unsigned char floppy_drives_installed;
|
|
||||||
volatile unsigned char i86_floppy_new_interrupt;
|
|
||||||
struct {
|
|
||||||
unsigned char type;
|
|
||||||
unsigned char data_rate;
|
|
||||||
unsigned char step_rate_time;
|
|
||||||
unsigned char head_load_time;
|
|
||||||
unsigned char head_unload_time;
|
|
||||||
unsigned char sectors_per_track;
|
|
||||||
} fd[2];
|
|
||||||
|
|
||||||
|
|
||||||
// Initialize DMA
|
|
||||||
unsigned char i86_floppy_initialize_dma(unsigned char* buffer, unsigned length)
|
|
||||||
{
|
|
||||||
union { unsigned char byt[4]; // Low[0], Mid[1], Hi[2]
|
|
||||||
unsigned long l;
|
|
||||||
} a, c;
|
|
||||||
|
|
||||||
a.l = (unsigned) buffer;
|
|
||||||
c.l = (unsigned) length-1;
|
|
||||||
|
|
||||||
// Check for buffer issues
|
|
||||||
if ((a.l >> 24) || (c.l >> 16) || (((a.l & 0xffff)+c.l) >> 16)) return 0;
|
|
||||||
|
|
||||||
i86_dma_reset();
|
|
||||||
i86_dma_mask_channel(2); // Mask channel 2
|
|
||||||
i86_dma_reset_flipflop(1); // FlipFlop reset on DMA1
|
|
||||||
|
|
||||||
i86_dma_set_address(2, a.byt[0], a.byt[1]); // Buffer address
|
|
||||||
i86_dma_reset_flipflop(1); // FlipFlop reset on DMA2
|
|
||||||
|
|
||||||
i86_dma_set_count(2, c.byt[0], c.byt[1]); // Set count
|
|
||||||
i86_dma_set_read(2);
|
|
||||||
i86_dma_unmask_all();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void i86_floppy_disable_controller() {
|
|
||||||
outportb (0x3F2, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void i86_floppy_enable_controller() {
|
|
||||||
outportb (0x3F2, 4 | 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline unsigned char i86_floppy_send_command (unsigned char command)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 750; i++)
|
|
||||||
if (inportb(0x3F4) & 128) {
|
|
||||||
outportb(0x3F5, command); return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline unsigned char i86_floppy_read_data ()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 750; i++)
|
|
||||||
if (inportb(0x3F4) & 0x80)
|
|
||||||
return inportb(0x3F5);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void i86_floppy_check_int(unsigned* st0, unsigned* cyl)
|
|
||||||
{
|
|
||||||
i86_floppy_send_command(0x8);
|
|
||||||
*st0 = i86_floppy_read_data();
|
|
||||||
*cyl = i86_floppy_read_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern unsigned i86_pit_get_tick_count();
|
|
||||||
extern unsigned i86_pit_get_frequency();
|
|
||||||
|
|
||||||
|
|
||||||
inline unsigned char i86_floppy_wait()
|
|
||||||
{
|
|
||||||
unsigned temp = i86_pit_get_tick_count();
|
|
||||||
unsigned freq = i86_pit_get_frequency();
|
|
||||||
|
|
||||||
while (i86_floppy_new_interrupt==0)
|
|
||||||
if (temp + (3*freq) == i86_pit_get_frequency()) return 0; // timeout
|
|
||||||
|
|
||||||
i86_floppy_new_interrupt = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_floppy_motor (unsigned char drive, unsigned char on)
|
|
||||||
{
|
|
||||||
if (drive >= floppy_drives_installed) return;
|
|
||||||
|
|
||||||
// Read DOR register
|
|
||||||
unsigned char dor = inportb(0x3F2);
|
|
||||||
|
|
||||||
// Un/set selected drive motor
|
|
||||||
if (on) dor |= drive << 4;
|
|
||||||
else dor &= ~(drive << 4);
|
|
||||||
|
|
||||||
// Write DOR
|
|
||||||
outportb (0x3F2, dor);
|
|
||||||
|
|
||||||
// Wait a fifth of a second for motor to turn on
|
|
||||||
unsigned temp = i86_pit_get_tick_count();
|
|
||||||
unsigned freq = i86_pit_get_frequency();
|
|
||||||
while (temp + (freq/5) > i86_pit_get_tick_count());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_floppy_handler(ISR_stack_regs *r)
|
|
||||||
{
|
|
||||||
i86_floppy_new_interrupt = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_floppy_drive_data (unsigned char drv, unsigned char dma)
|
|
||||||
{
|
|
||||||
unsigned data = 0;
|
|
||||||
if (drv >= floppy_drives_installed) return;
|
|
||||||
|
|
||||||
outportb(0x3F7, fd[drv].data_rate);
|
|
||||||
|
|
||||||
i86_floppy_send_command (0x3);
|
|
||||||
|
|
||||||
data = ((fd[drv].step_rate_time & 0xf) << 4) | (fd[drv].head_unload_time & 0xf);
|
|
||||||
i86_floppy_send_command (data);
|
|
||||||
|
|
||||||
data = (fd[drv].head_load_time <<1 ) | (dma) ? 1 : 0;
|
|
||||||
i86_floppy_send_command (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void i86_floppy_select(unsigned char drive)
|
|
||||||
{
|
|
||||||
if (drive >= floppy_drives_installed) return;
|
|
||||||
|
|
||||||
// Send mechanical drive data
|
|
||||||
i86_floppy_drive_data(drive, 1);
|
|
||||||
|
|
||||||
// Select drive in DOR register
|
|
||||||
outportb (0x3F2, 4 | 8 | drive);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char i86_floppy_calibrate(unsigned drive)
|
|
||||||
{
|
|
||||||
unsigned st0, cyl;
|
|
||||||
|
|
||||||
if (drive >= floppy_drives_installed) return 0;
|
|
||||||
|
|
||||||
i86_floppy_motor (drive, 1);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 15; i++) {
|
|
||||||
i86_floppy_new_interrupt = 0;
|
|
||||||
i86_floppy_send_command(0x7);
|
|
||||||
i86_floppy_send_command(drive);
|
|
||||||
i86_floppy_wait();
|
|
||||||
i86_floppy_check_int(&st0, &cyl);
|
|
||||||
|
|
||||||
if (!cyl) {
|
|
||||||
i86_floppy_motor(drive, 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i86_floppy_motor(drive, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_floppy_reset()
|
|
||||||
{
|
|
||||||
unsigned st0, cyl;
|
|
||||||
|
|
||||||
i86_floppy_new_interrupt = 0;
|
|
||||||
i86_floppy_disable_controller();
|
|
||||||
i86_floppy_enable_controller();
|
|
||||||
i86_floppy_wait();
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
i86_floppy_check_int(&st0, &cyl);
|
|
||||||
|
|
||||||
unsigned char drive;
|
|
||||||
for (drive = 0; drive < floppy_drives_installed; drive++) {
|
|
||||||
i86_floppy_drive_data(drive, 1);
|
|
||||||
i86_floppy_calibrate(drive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i86_floppy_read_sector_imp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector)
|
|
||||||
{
|
|
||||||
unsigned st0, cyl;
|
|
||||||
|
|
||||||
i86_floppy_select (drive);
|
|
||||||
i86_floppy_initialize_dma((unsigned char*) where, 512);
|
|
||||||
i86_dma_set_read(2);
|
|
||||||
|
|
||||||
i86_floppy_new_interrupt = 0;
|
|
||||||
|
|
||||||
i86_floppy_send_command(0x06 | 0x80 | 0x40 );
|
|
||||||
i86_floppy_send_command(head<<2 | drive);
|
|
||||||
i86_floppy_send_command(track);
|
|
||||||
i86_floppy_send_command(head);
|
|
||||||
i86_floppy_send_command(sector);
|
|
||||||
i86_floppy_send_command(0x02);
|
|
||||||
i86_floppy_send_command( ((sector+1) >= fd[drive].sectors_per_track) ? fd[drive].sectors_per_track : sector+1);
|
|
||||||
i86_floppy_send_command(0x1b);
|
|
||||||
i86_floppy_send_command(0xff);
|
|
||||||
|
|
||||||
i86_floppy_wait();
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 7; i++) i86_floppy_read_data();
|
|
||||||
|
|
||||||
i86_floppy_check_int (&st0, &cyl);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char i86_floppy_seek (unsigned drive, unsigned cyl, unsigned head)
|
|
||||||
{
|
|
||||||
unsigned st0, cyl0;
|
|
||||||
|
|
||||||
if (drive >= floppy_drives_installed) return 0;
|
|
||||||
|
|
||||||
i86_floppy_select (drive);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 20; i++) {
|
|
||||||
i86_floppy_new_interrupt = 0;
|
|
||||||
i86_floppy_send_command (0xF);
|
|
||||||
i86_floppy_send_command ( (head) << 2 | drive);
|
|
||||||
i86_floppy_send_command (cyl);
|
|
||||||
|
|
||||||
i86_floppy_wait();
|
|
||||||
i86_floppy_check_int(&st0, &cyl0);
|
|
||||||
|
|
||||||
if (cyl0 == cyl) return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void i86_floppy_lba_to_chs (int lba, unsigned char drive, unsigned char *head, unsigned char *track, unsigned char *sectors)
|
|
||||||
{
|
|
||||||
*head = (lba % (fd[drive].sectors_per_track * 2)) / fd[drive].sectors_per_track;
|
|
||||||
*track = lba / (fd[drive].sectors_per_track * 2);
|
|
||||||
*sectors = lba % fd[drive].sectors_per_track + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern unsigned char i86_cmos_read_floppy_drives();
|
|
||||||
const char* types[] = {
|
|
||||||
"Nonexistant", "5.25\", unsupported.", "5.25\", unsupported.",
|
|
||||||
"3.5\", 720kb", "3.5\", 1.44mb", "3.5\", 2.88 mb"};
|
|
||||||
|
|
||||||
void i86_floppy_install()
|
|
||||||
{
|
|
||||||
unsigned char temp = i86_cmos_read_floppy_drives();
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Set fd0 and fd1 types
|
|
||||||
fd[1].type = temp & 0xf;
|
|
||||||
fd[0].type = temp >> 4;
|
|
||||||
|
|
||||||
// SRT = 16 - (ms * datarate / 500000);
|
|
||||||
// HLT = ms * datarate / 1000000
|
|
||||||
// HUT = ms * datarate / 8000000
|
|
||||||
|
|
||||||
// Set up
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (fd[i].type >= 3) floppy_drives_installed++; // 5.25" drives unsupported
|
|
||||||
if (fd[i].type == 3) { // 720 kb, DD
|
|
||||||
fd[i].data_rate = 2; // speed = 250 kbps
|
|
||||||
fd[i].step_rate_time = 12; // 16 - (ms * 250000 / 500000), ms = 8
|
|
||||||
fd[i].head_load_time = 7;
|
|
||||||
fd[i].head_unload_time = 7;
|
|
||||||
fd[i].sectors_per_track = 9;
|
|
||||||
}
|
|
||||||
else if (fd[i].type == 4) { // 1.44 MB, HD
|
|
||||||
fd[i].data_rate = 0; // speed = 500 kbps
|
|
||||||
fd[i].step_rate_time = 8;
|
|
||||||
fd[i].head_load_time = 15;
|
|
||||||
fd[i].head_unload_time = 15;
|
|
||||||
fd[i].sectors_per_track = 18;
|
|
||||||
}
|
|
||||||
else if (fd[i].type == 5) { // 2.88 MB, ED
|
|
||||||
fd[i].data_rate = 3; // speed = 1000 kbps;
|
|
||||||
fd[i].step_rate_time = 0;
|
|
||||||
fd[i].head_load_time = 30;
|
|
||||||
fd[i].head_unload_time = 30;
|
|
||||||
fd[i].sectors_per_track = 36;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (floppy_drives_installed == 0) return; // No drives to set
|
|
||||||
|
|
||||||
// Install handler
|
|
||||||
i86_irq_install_handler(6, i86_floppy_handler);
|
|
||||||
i86_floppy_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char i86_floppy_driver_enabled()
|
|
||||||
{
|
|
||||||
return (floppy_drives_installed>0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned* i86_read_sector (unsigned* where, unsigned char drive, int sectorLBA)
|
|
||||||
{
|
|
||||||
if (drive >= floppy_drives_installed) return 0;
|
|
||||||
if ((unsigned)(where) > (0xFFFF - 513)) return 0;
|
|
||||||
|
|
||||||
// convert lba to chs
|
|
||||||
unsigned head, track, sector;
|
|
||||||
i86_floppy_lba_to_chs(sectorLBA, drive, (unsigned char*)&head, (unsigned char*)&track, (unsigned char*) §or);
|
|
||||||
|
|
||||||
// start motor
|
|
||||||
i86_floppy_motor(drive, 1);
|
|
||||||
if (!i86_floppy_seek(drive, track, head)) return 0;
|
|
||||||
|
|
||||||
i86_floppy_read_sector_imp(where, drive, head, track, sector);
|
|
||||||
i86_floppy_motor(drive, 0);
|
|
||||||
|
|
||||||
return (unsigned*)where;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/***** floppy.h ******************************************************
|
|
||||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
|
||||||
* *
|
|
||||||
* Floppy Drive I/O Routines *
|
|
||||||
* ========================= *
|
|
||||||
* *
|
|
||||||
************************************************************ cta os */
|
|
||||||
|
|
||||||
extern unsigned char i86_floppy_initialize_dma(unsigned char* buffer, unsigned length);
|
|
||||||
extern void i86_floppy_motor (unsigned char drive, unsigned char on);
|
|
||||||
extern void i86_floppy_handler(ISR_stack_regs *r);
|
|
||||||
extern void i86_floppy_drive_data (unsigned char drv, unsigned char dma);
|
|
||||||
extern unsigned char i86_floppy_calibrate(unsigned drive);
|
|
||||||
extern void i86_floppy_reset();
|
|
||||||
extern void i86_floppy_read_sector_imp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector);
|
|
||||||
extern unsigned char i86_floppy_seek (unsigned drive, unsigned cyl, unsigned head);
|
|
||||||
extern void i86_floppy_install();
|
|
||||||
extern unsigned char i86_floppy_driver_enabled();
|
|
||||||
extern unsigned* i86_read_sector (unsigned* where, unsigned char drive, int sectorLBA);
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%nasm_path%\nasm.exe -f aout -o %objpath%/gdt_asm.o gdt.asm
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/gdt.o gdt.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
#include <system.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <hal.h>
|
|
||||||
#include "cpu/cpu.h"
|
|
||||||
#include "gdt/gdt.h"
|
|
||||||
#include "idt/idt.h"
|
|
||||||
#include "pic/pic.h"
|
|
||||||
#include "pit/pit.h"
|
|
||||||
#include "cmos/cmos.h"
|
|
||||||
#include "irq/irq.h"
|
|
||||||
#include "isrs/isrs.h"
|
|
||||||
#include "keyboard/keyus.h"
|
|
||||||
#include "floppy/floppy.h"
|
|
||||||
|
|
||||||
// initialize hardware devices
|
|
||||||
void i86_hal_initialize () {
|
|
||||||
|
|
||||||
// initialize motherboard controllers and system timer
|
|
||||||
i86_cpu_initialize (); // (install GDT, IDT)
|
|
||||||
i86_isrs_install(); // (install ISR handler)
|
|
||||||
i86_irq_install(); // (install IRQ handler)
|
|
||||||
|
|
||||||
// install PIT and system clock; pit at 100 Hz
|
|
||||||
i86_kb_install_partone();
|
|
||||||
i86_cmos_read_clock((TIME*)&_internal_clock);
|
|
||||||
i86_pit_install (100);
|
|
||||||
i86_kb_install_parttwo();
|
|
||||||
|
|
||||||
// enable interrupts
|
|
||||||
i86_start_interrupts();
|
|
||||||
|
|
||||||
i86_floppy_install();
|
|
||||||
}
|
|
||||||
|
|
||||||
// shutdown hardware devices
|
|
||||||
int i86_hal_shutdown () {
|
|
||||||
|
|
||||||
i86_cpu_shutdown ();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reboot()
|
|
||||||
{
|
|
||||||
unsigned char good = 0x02;
|
|
||||||
while ((good & 0x02) != 0)
|
|
||||||
good = inportb(0x64);
|
|
||||||
outportb(0x64, 0xFE);
|
|
||||||
__asm__ __volatile__ ("hlt");
|
|
||||||
}
|
|
||||||
|
|
||||||
//! output sound to speaker
|
|
||||||
void sound (unsigned frequency) {
|
|
||||||
|
|
||||||
//! sets frequency for speaker. frequency of 0 disables speaker
|
|
||||||
outportb (0x61, 3 | (unsigned char)(frequency<<2) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! returns cpu vender
|
|
||||||
const char* get_cpu_vender () {
|
|
||||||
|
|
||||||
return i86_cpu_get_vender();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************
|
|
||||||
* Keyboard Routines *
|
|
||||||
***************************************************************************************/
|
|
||||||
/*char getch()
|
|
||||||
{
|
|
||||||
-> moved in conio library
|
|
||||||
}*/
|
|
||||||
|
|
||||||
char scancode_to_ascii(unsigned char scancode, unsigned char status)
|
|
||||||
{
|
|
||||||
if ((status&1) || (status&2)) return kbdus_map_shift[scancode];
|
|
||||||
else return kbdus_map[scancode];
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char get_key_status (unsigned char scancode)
|
|
||||||
{
|
|
||||||
if (scancode&0xF0) return kb_lights_status&0x0F;
|
|
||||||
else if (scancode&0x80) return kb_modifier_status&0x7F;
|
|
||||||
|
|
||||||
return i86_kb_get_key(scancode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************
|
|
||||||
* Set repeat rate/delay *
|
|
||||||
***************************************
|
|
||||||
Values for inter-character delay (bits 4-0)
|
|
||||||
(characters per second; default is 10.9)
|
|
||||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
|
||||||
----+----+----+----+----+----+----+----+----
|
|
||||||
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
|
|
||||||
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
|
|
||||||
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
|
|
||||||
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
|
|
||||||
|
|
||||||
Values for delay:
|
|
||||||
(miliseconds; default is 500)
|
|
||||||
0 | 1 | 2 | 3
|
|
||||||
-----+-----+-----+-----
|
|
||||||
250 | 500 | 750 | 1000
|
|
||||||
|
|
||||||
***************************************/
|
|
||||||
void kb_set_repeat(float rate, int delay){
|
|
||||||
float rates[] = {30.0, 26.7, 24.0, 21.8, 20.0, 18.5, 17.1, 16.0, 15.0, 13.3, 12.0,
|
|
||||||
10.9, 10.0, 9.2, 8.6, 8.0, 7.5, 6.7, 6.0, 5.5, 5.0, 4.6, 4.3, 4.0,
|
|
||||||
3.7, 3.3, 3.0, 2.7, 2.5, 2.3, 2.1, 2.0} ;
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char r,d;
|
|
||||||
|
|
||||||
for (r = 0; rate != rates[r] && r < 32; r++)
|
|
||||||
if (rate==32) return;
|
|
||||||
|
|
||||||
switch(delay) {
|
|
||||||
case 250: d = 0; break;
|
|
||||||
case 500: d = 1; break;
|
|
||||||
case 750: d = 2; break;
|
|
||||||
case 1000: d = 3; break;
|
|
||||||
default: return;
|
|
||||||
}
|
|
||||||
|
|
||||||
i86_kb_set_repeat(r,d);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************
|
|
||||||
* Set keyboard LEDs *
|
|
||||||
***************************************
|
|
||||||
+-----------+-------+-------+--------+
|
|
||||||
| Bits 7-3 | Bit 2 | Bit 1 | Bit 0 |
|
|
||||||
| 0 | Caps | Num | Scroll |
|
|
||||||
|(reserved) | lock | lock | lock |
|
|
||||||
+-----------+-------+-------+--------+
|
|
||||||
***************************************/
|
|
||||||
void kb_set_LEDs(unsigned char status) {
|
|
||||||
i86_kb_set_LEDs(status);
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%nasm_path%\nasm.exe -f aout -o %objpath%/idt_asm.o idt.asm
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/idt.o idt.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%nasm_path%\nasm.exe -f aout -o %objpath%/irq_asm.o irq.asm
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/irq.o irq.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
#include <system.h>
|
|
||||||
#include "../idt/idt.h"
|
|
||||||
#include "../pic/pic.h"
|
|
||||||
#include "irq.h"
|
|
||||||
/* This array is actually an array of function pointers. We use
|
|
||||||
* this to handle custom IRQ handlers for a given IRQ */
|
|
||||||
void *irq_routines[16] =
|
|
||||||
{
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This installs a custom IRQ handler for the given IRQ */
|
|
||||||
void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r))
|
|
||||||
{
|
|
||||||
irq_routines[irq] = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
void i86_irq_uninstall_handler (int irq)
|
|
||||||
{
|
|
||||||
irq_routines[irq] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* We first remap the interrupt controllers, and then we install
|
|
||||||
* the appropriate ISRs to the correct entries in the IDT. This
|
|
||||||
* is just like installing the exception handlers */
|
|
||||||
void i86_irq_install()
|
|
||||||
{
|
|
||||||
i86_pic_remap(32,40);
|
|
||||||
|
|
||||||
i86_idt_set_gate(32, (unsigned)i86_irq0, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(33, (unsigned)i86_irq1, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(34, (unsigned)i86_irq2, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(35, (unsigned)i86_irq3, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(36, (unsigned)i86_irq4, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(37, (unsigned)i86_irq5, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(38, (unsigned)i86_irq6, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(39, (unsigned)i86_irq7, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(40, (unsigned)i86_irq8, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(41, (unsigned)i86_irq9, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(42, (unsigned)i86_irq10, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(43, (unsigned)i86_irq11, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(44, (unsigned)i86_irq12, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(45, (unsigned)i86_irq13, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(46, (unsigned)i86_irq14, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(47, (unsigned)i86_irq15, 0x08, 0x8E);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Each of the IRQ ISRs point to this function, rather than
|
|
||||||
* the 'fault_handler' in 'isrs.c'. The IRQ Controllers need
|
|
||||||
* to be told when you are done servicing them, so you need
|
|
||||||
* to send them an "End of Interrupt" command (0x20). There
|
|
||||||
* are two 8259 chips: The first exists at 0x20, the second
|
|
||||||
* exists at 0xA0. If the second controller (an IRQ from 8 to
|
|
||||||
* 15) gets an interrupt, you need to acknowledge the
|
|
||||||
* interrupt at BOTH controllers, otherwise, you only send
|
|
||||||
* an EOI command to the first controller. If you don't send
|
|
||||||
* an EOI, you won't raise any more IRQs */
|
|
||||||
void i86_irq_handler (ISR_stack_regs *r)
|
|
||||||
{
|
|
||||||
/* This is a blank function pointer */
|
|
||||||
void (*handler)(ISR_stack_regs *r);
|
|
||||||
|
|
||||||
/* Find out if we have a custom handler to run for this
|
|
||||||
* IRQ, and then finally, run it */
|
|
||||||
handler = irq_routines[r->int_no - 32];
|
|
||||||
if (handler) handler(r);
|
|
||||||
|
|
||||||
/* If the IDT entry that was invoked was greater than 40
|
|
||||||
* (meaning IRQ8 - 15), then we need to send an EOI to
|
|
||||||
* the slave controller */
|
|
||||||
if (r->int_no >=40) outportb(0x0A, 0x20);
|
|
||||||
|
|
||||||
/* In either case, we need to send an EOI to the master
|
|
||||||
* interrupt controller too */
|
|
||||||
outportb(0x20, 0x20);
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#ifndef __IRQ_H
|
|
||||||
#define __IRQ_H
|
|
||||||
|
|
||||||
#include <regs.h>
|
|
||||||
|
|
||||||
/* These are own ISRs that point to our special IRQ handler
|
|
||||||
* instead of the regular 'fault_handler' function */
|
|
||||||
|
|
||||||
extern void i86_irq0();
|
|
||||||
extern void i86_irq1();
|
|
||||||
extern void i86_irq2();
|
|
||||||
extern void i86_irq3();
|
|
||||||
extern void i86_irq4();
|
|
||||||
extern void i86_irq5();
|
|
||||||
extern void i86_irq6();
|
|
||||||
extern void i86_irq7();
|
|
||||||
extern void i86_irq8();
|
|
||||||
extern void i86_irq9();
|
|
||||||
extern void i86_irq10();
|
|
||||||
extern void i86_irq11();
|
|
||||||
extern void i86_irq12();
|
|
||||||
extern void i86_irq13();
|
|
||||||
extern void i86_irq14();
|
|
||||||
extern void i86_irq15();
|
|
||||||
|
|
||||||
extern void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r));
|
|
||||||
extern void i86_irq_uninstall_handler (int irq);
|
|
||||||
extern void i86_irq_install();
|
|
||||||
extern void i86_irq_handler (ISR_stack_regs *r);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%nasm_path%\nasm.exe -f aout -o %objpath%/isrs_asm.o isrs.asm
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/isrs.o isrs.c
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/BSOD.o BSOD.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
#include <system.h>
|
|
||||||
#include "isrs.h"
|
|
||||||
#include "../idt/idt.h"
|
|
||||||
|
|
||||||
extern void _STOP_ERROR_SCREEN(ISR_stack_regs *);
|
|
||||||
/* This is a very repetitive function... it's not hard, it's
|
|
||||||
* just annoying. As you can see, we set the first 32 entries
|
|
||||||
* in the IDT to the first 32 ISRs. We can't use a for loop
|
|
||||||
* for this, because there is no way to get the function names
|
|
||||||
* that correspond to that given entry. We set the access
|
|
||||||
* flags to 0x8E. This means that the entry is present, is
|
|
||||||
* running in ring 0 (kernel level), and has the lower 5 bits
|
|
||||||
* set to the required '14', which is represented by 'E' in
|
|
||||||
* hex. */
|
|
||||||
void i86_isrs_install()
|
|
||||||
{
|
|
||||||
i86_idt_set_gate(0, (unsigned)i86_isr0, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(1, (unsigned)i86_isr1, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(2, (unsigned)i86_isr2, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(3, (unsigned)i86_isr3, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(4, (unsigned)i86_isr4, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(5, (unsigned)i86_isr5, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(6, (unsigned)i86_isr6, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(7, (unsigned)i86_isr7, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(8, (unsigned)i86_isr8, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(9, (unsigned)i86_isr9, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(10, (unsigned)i86_isr10, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(11, (unsigned)i86_isr11, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(12, (unsigned)i86_isr12, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(13, (unsigned)i86_isr13, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(14, (unsigned)i86_isr14, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(15, (unsigned)i86_isr15, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(16, (unsigned)i86_isr16, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(17, (unsigned)i86_isr17, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(18, (unsigned)i86_isr18, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(19, (unsigned)i86_isr19, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(20, (unsigned)i86_isr20, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(21, (unsigned)i86_isr21, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(22, (unsigned)i86_isr22, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(23, (unsigned)i86_isr23, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(24, (unsigned)i86_isr24, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(25, (unsigned)i86_isr25, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(26, (unsigned)i86_isr26, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(27, (unsigned)i86_isr27, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(28, (unsigned)i86_isr28, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(29, (unsigned)i86_isr29, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(30, (unsigned)i86_isr30, 0x08, 0x8E);
|
|
||||||
i86_idt_set_gate(31, (unsigned)i86_isr31, 0x08, 0x8E);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* All of our Exception handling Interrupt Service Routines will
|
|
||||||
* point to this function. This will tell us what exception has
|
|
||||||
* happened! Right now, we simply halt the system by hitting an
|
|
||||||
* endless loop. All ISRs disable interrupts while they are being
|
|
||||||
* serviced as a 'locking' mechanism to prevent an IRQ from
|
|
||||||
* happening and messing up kernel data structures */
|
|
||||||
void i86_fault_handler(ISR_stack_regs *r)
|
|
||||||
{
|
|
||||||
/* Is this a fault whose number is from 0 to 31? */
|
|
||||||
if (r->int_no < 32)
|
|
||||||
{
|
|
||||||
_STOP_ERROR_SCREEN(r);
|
|
||||||
/* Display the description for the Exception that occurred.*/
|
|
||||||
|
|
||||||
/* Put on the BSOD screen*/
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#ifndef __ISRS_H
|
|
||||||
#define __ISRS_H
|
|
||||||
|
|
||||||
extern void i86_isr0();
|
|
||||||
extern void i86_isr1();
|
|
||||||
extern void i86_isr2();
|
|
||||||
extern void i86_isr3();
|
|
||||||
extern void i86_isr4();
|
|
||||||
extern void i86_isr5();
|
|
||||||
extern void i86_isr6();
|
|
||||||
extern void i86_isr7();
|
|
||||||
extern void i86_isr8();
|
|
||||||
extern void i86_isr9();
|
|
||||||
extern void i86_isr10();
|
|
||||||
extern void i86_isr11();
|
|
||||||
extern void i86_isr12();
|
|
||||||
extern void i86_isr13();
|
|
||||||
extern void i86_isr14();
|
|
||||||
extern void i86_isr15();
|
|
||||||
extern void i86_isr16();
|
|
||||||
extern void i86_isr17();
|
|
||||||
extern void i86_isr18();
|
|
||||||
extern void i86_isr19();
|
|
||||||
extern void i86_isr20();
|
|
||||||
extern void i86_isr21();
|
|
||||||
extern void i86_isr22();
|
|
||||||
extern void i86_isr23();
|
|
||||||
extern void i86_isr24();
|
|
||||||
extern void i86_isr25();
|
|
||||||
extern void i86_isr26();
|
|
||||||
extern void i86_isr27();
|
|
||||||
extern void i86_isr28();
|
|
||||||
extern void i86_isr29();
|
|
||||||
extern void i86_isr30();
|
|
||||||
extern void i86_isr31();
|
|
||||||
|
|
||||||
extern void i86_isrs_install();
|
|
||||||
extern void i86_fault_handler(ISR_stack_regs *r);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/keyus.o keyus.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
|
|
||||||
#define KB_KEY_LSHIFT 0x81 // 1000 0001
|
|
||||||
#define KB_KEY_RSHIFT 0X82 // 1000 0010
|
|
||||||
#define KB_KEY_LALT 0X84 // 1000 0100
|
|
||||||
#define KB_KEY_RALT 0x88 // 1000 1000
|
|
||||||
#define KB_KEY_LCTRL 0x90 // 1001 0000
|
|
||||||
#define KB_KEY_RCTRL 0xA0 // 1010 0000
|
|
||||||
#define KB_KEY_FSHIFT 0xC0 // 1100 0000
|
|
||||||
extern volatile unsigned char kb_modifier_status;
|
|
||||||
|
|
||||||
#define KB_PREFIX_GRAY 0x01 // Gray
|
|
||||||
#define KB_PREFIX_BREAK 0x02 // Break code
|
|
||||||
#define KB_PREFIX_PAUSE 0x04 // Pause/break key
|
|
||||||
#define KB_PREFIX_PAUSE1 0x08 // Recieved first unsigned char from pause/break
|
|
||||||
extern volatile unsigned char kb_prefix;
|
|
||||||
|
|
||||||
#define KB_KEY_SCROLL 0xF1 // 1111 0001
|
|
||||||
#define KB_KEY_NUM 0xF2 // 1111 0010
|
|
||||||
#define KB_KEY_CAPS 0xF4 // 1111 0100
|
|
||||||
extern volatile unsigned char kb_lights_status;
|
|
||||||
|
|
||||||
extern unsigned char kb_scancode_set;
|
|
||||||
|
|
||||||
enum KB_KEYS {
|
|
||||||
KB_KEY_PAUSE = 0x00
|
|
||||||
KB_KEY_F9 = 0x01
|
|
||||||
KB_KEY_F7 = 0x02
|
|
||||||
KB_KEY_F5 = 0X03
|
|
||||||
KB_KEY_F3 = 0x04
|
|
||||||
KB_KEY_F1 = 0x05
|
|
||||||
KB_KEY_F2 = 0x06
|
|
||||||
KB_KEY_F12 = 0x07
|
|
||||||
KB_KEY_PRINTSCRN = 0x08
|
|
||||||
KB_KEY_F10 = 0x09
|
|
||||||
KB_KEY_F8 = 0x0A
|
|
||||||
KB_KEY_F6 = 0x0B
|
|
||||||
KB_KEY_F4 = 0x0C
|
|
||||||
KB_KEY_TAB = 0x0D
|
|
||||||
KB_KEY_TILDA = 0x0E
|
|
||||||
KB_KEY_Q = 0x15
|
|
||||||
KB_KEY_1 = 0x16
|
|
||||||
KB_KEY_Z = 0x1A
|
|
||||||
KB_KEY_S = 0x1B
|
|
||||||
KB_KEY_A = 0x1C
|
|
||||||
KB_KEY_W = 0x1D
|
|
||||||
KB_KEY_2 = 0x1E
|
|
||||||
KB_KEY_LWIN = 0x1F
|
|
||||||
KB_KEY_C = 0x21
|
|
||||||
KB_KEY_X = 0x22
|
|
||||||
KB_KEY_D = 0x23
|
|
||||||
KB_KEY_E = 0x24
|
|
||||||
KB_KEY_4 = 0x25
|
|
||||||
KB_KEY_3 = 0x26
|
|
||||||
KB_KEY_RWIN = 0x27
|
|
||||||
KB_KEY_SPACE = 0x29
|
|
||||||
KB_KEY_V = 0x2A
|
|
||||||
KB_KEY_F = 0x2B
|
|
||||||
KB_KEY_T = 0x2C
|
|
||||||
KB_KEY_R = 0x2D
|
|
||||||
KB_KEY_5 = 0x2E
|
|
||||||
KB_KEY_MENU = 0x2F
|
|
||||||
KB_KEY_N = 0x31
|
|
||||||
KB_KEY_B = 0x32
|
|
||||||
KB_KEY_H = 0x33
|
|
||||||
KB_KEY_G = 0x34
|
|
||||||
KB_KEY_Y = 0x35
|
|
||||||
KB_KEY_6 = 0x36
|
|
||||||
KB_KEY_M = 0x3A
|
|
||||||
KB_KEY_J = 0x3B
|
|
||||||
KB_KEY_U = 0x3C
|
|
||||||
KB_KEY_7 = 0x3D
|
|
||||||
KB_KEY_8 = 0x3E
|
|
||||||
KB_KEY_COMMA = 0x41
|
|
||||||
KB_KEY_K = 0x42
|
|
||||||
KB_KEY_I = 0x43
|
|
||||||
KB_KEY_O = 0x44
|
|
||||||
KB_KEY_0 = 0x45
|
|
||||||
KB_KEY_9 = 0x46
|
|
||||||
KB_KEY_PERIOD = 0x49
|
|
||||||
KB_KEY_SLASH = 0x4A
|
|
||||||
KB_KEY_L = 0x4B
|
|
||||||
KB_KEY_SEMICOLON = 0x4C
|
|
||||||
KB_KEY_P = 0x4D
|
|
||||||
KB_KEY_DASH = 0x4E
|
|
||||||
KB_KEY_APOSTROPHE = 0x52
|
|
||||||
KB_KEY_LBRACKET = 0x54
|
|
||||||
KB_KEY_EQUAL = 0x55
|
|
||||||
KB_KEY_NUMPAD_ENTER = 0x59
|
|
||||||
KB_KEY_ENTER = 0x5A
|
|
||||||
KB_KEY_RBRACKET = 0x5B
|
|
||||||
KB_KEY_BACKSLASH = 0x5D
|
|
||||||
KB_KEY_END = 0x5E
|
|
||||||
KB_KEY_LEFT = 0x5F
|
|
||||||
KB_KEY_HOME = 0x60
|
|
||||||
KB_KEY_INSERT = 0x61
|
|
||||||
KB_KEY_DELETE = 0x62
|
|
||||||
KB_KEY_DOWN = 0x63
|
|
||||||
KB_KEY_RIGHT = 0x64
|
|
||||||
KB_KEY_UP = 0x65
|
|
||||||
KB_KEY_BACKSPACE = 0x66
|
|
||||||
KB_KEY_PGDOWN = 0x67
|
|
||||||
KB_KEY_PGUP = 0x68
|
|
||||||
KB_KEY_NUMPAD_1 = 0x69
|
|
||||||
KB_KEY_NUMPAD_SLASH = 0x6A
|
|
||||||
KB_KEY_NUMPAD_4 = 0x6B
|
|
||||||
KB_KEY_NUMPAD_7 = 0x6C
|
|
||||||
KB_KEY_NUMPAD_0 = 0x70
|
|
||||||
KB_KEY_NUMPAD_COLON = 0x71
|
|
||||||
KB_KEY_NUMPAD_2 = 0x72
|
|
||||||
KB_KEY_NUMPAD_5 = 0x73
|
|
||||||
KB_KEY_NUMPAD_6 = 0x74
|
|
||||||
KB_KEY_NUMPAD_8 = 0x75
|
|
||||||
KB_KEY_ESC = 0x76
|
|
||||||
KB_KEY_F11 = 0x78
|
|
||||||
KB_KEY_NUMPAD_PLUS = 0x79
|
|
||||||
KB_KEY_NUMPAD_3 = 0x7A
|
|
||||||
KB_KEY_NUMPAD_MINUS = 0x7B
|
|
||||||
KB_KEY_NUMPAD_ASTERISK = 0x7C
|
|
||||||
KB_KEY_NUMPAD_9 = 0x7D
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned char status;
|
|
||||||
unsigned char lights;
|
|
||||||
unsigned char scancode;
|
|
||||||
unsigned char character;
|
|
||||||
} kb_key;
|
|
||||||
|
|
||||||
|
|
||||||
extern char getch();
|
|
||||||
extern kb_key get_key();
|
|
||||||
extern scancode_to_ascii(unsigned char scancode);
|
|
||||||
extern unsigned char get_key_status(unsigned char scancode);
|
|
||||||
extern void kb_set_repeat(float rate, int delay);
|
|
||||||
extern void kb_set_LEDs(unsigned char status);
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#ifndef __KEYUS_H
|
|
||||||
#define __KEYUS_H
|
|
||||||
|
|
||||||
extern const char kbdus_map[0x80];
|
|
||||||
extern const char kbdus_map_shift[0x80];
|
|
||||||
|
|
||||||
extern volatile unsigned char kb_modifier_status;
|
|
||||||
extern volatile unsigned char kb_prefix;
|
|
||||||
extern volatile unsigned char kb_lights_status;
|
|
||||||
extern unsigned char kb_scancode_set;
|
|
||||||
|
|
||||||
extern void i86_kb_set_key(unsigned char scancode, unsigned char val);
|
|
||||||
extern void i86_kb_set_LEDs(unsigned char status);
|
|
||||||
extern void i86_kb_set_repeat(unsigned char rate, unsigned char delay);
|
|
||||||
extern void i86_kb_set_scancodeset(unsigned char set);
|
|
||||||
extern unsigned char i86_kb_get_key(unsigned char scancode);
|
|
||||||
extern void i86_kb_handler(ISR_stack_regs *r);
|
|
||||||
extern kb_key getkey();
|
|
||||||
extern void i86_kb_set_repeat(unsigned char rate, unsigned char delay);
|
|
||||||
extern void i86_kb_set_LEDs(unsigned char status);
|
|
||||||
extern void i86_kb_set_scancodeset(unsigned char set);
|
|
||||||
extern unsigned char i86_kb_get_scancodeset();
|
|
||||||
extern void i86_kb_waitin();
|
|
||||||
extern void i86_kb_waitout();
|
|
||||||
extern void i86_kb_install_partone();
|
|
||||||
extern int i86_kb_install_parttwo();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
@echo off
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
|
|
||||||
@echo Building Hardware Abstraction Layer...
|
|
||||||
set objpath=..\objects
|
|
||||||
set incpath=../include
|
|
||||||
del %objpath%\hal.o
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/hal.o hal.c
|
|
||||||
if not exist %objpath%\hal.o goto error
|
|
||||||
|
|
||||||
set objpath=..\..\objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
goto cmos
|
|
||||||
|
|
||||||
:error
|
|
||||||
@echo.
|
|
||||||
@echo There have been build errors. Building halted.
|
|
||||||
@pause
|
|
||||||
exit
|
|
||||||
|
|
||||||
:cmos
|
|
||||||
cd cmos
|
|
||||||
@echo * Compiling CMOS...
|
|
||||||
del %objpath%\cmos.o
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cmos.o cmos.c
|
|
||||||
if not exist %objpath%\cmos.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
:cpu
|
|
||||||
cd cpu
|
|
||||||
@echo * Compiling Central Processing Unit (CPU)...
|
|
||||||
del %objpath%\cpu.o
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cpu.o cpu.c
|
|
||||||
if not exist %objpath%\cpu.o goto error
|
|
||||||
|
|
||||||
cd..
|
|
||||||
|
|
||||||
|
|
||||||
:dma
|
|
||||||
cd dma
|
|
||||||
@echo * Compiling Direct Memory Access Controller (DMAC)...
|
|
||||||
del %objpath%\dma.o
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/dma.o dma.c
|
|
||||||
if not exist %objpath%\dma.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
|
|
||||||
:floppy
|
|
||||||
cd floppy
|
|
||||||
@echo * Compiling Floppy Driver...
|
|
||||||
del %objpath%\floppy.o
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/floppy.o floppy.c
|
|
||||||
if not exist %objpath%\floppy.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
:gdt
|
|
||||||
cd gdt
|
|
||||||
@echo * Compiling Global Descriptor Table...
|
|
||||||
del %objpath%\gdt.o
|
|
||||||
del %objpath%\gdt_asm.o
|
|
||||||
%nasm_path%\nasm.exe -f aout -o %objpath%/gdt_asm.o gdt.asm
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/gdt.o gdt.c
|
|
||||||
if not exist %objpath%\gdt.o goto error
|
|
||||||
if not exist %objpath%\gdt_asm.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
:idt
|
|
||||||
cd idt
|
|
||||||
@echo * Compiling Interrupt Descriptor Table...
|
|
||||||
del %objpath%\idt.o
|
|
||||||
del %objpath%\idt_asm.o
|
|
||||||
%nasm_path%\nasm.exe -f aout -o %objpath%/idt_asm.o idt.asm
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/idt.o idt.c
|
|
||||||
if not exist %objpath%\idt.o goto error
|
|
||||||
if not exist %objpath%\idt_asm.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
:irq
|
|
||||||
cd irq
|
|
||||||
@echo * Compiling Interrupt ReQuests...
|
|
||||||
del %objpath%\irq.o
|
|
||||||
del %objpath%\irq_asm.o
|
|
||||||
%nasm_path%\nasm.exe -f aout -o %objpath%/irq_asm.o irq.asm
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/irq.o irq.c
|
|
||||||
if not exist %objpath%\irq.o goto error
|
|
||||||
if not exist %objpath%\irq_asm.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
:isrs
|
|
||||||
cd isrs
|
|
||||||
@echo * Compiling Interrupt Service Routines...
|
|
||||||
del %objpath%\isrs_asm.o
|
|
||||||
del %objpath%\isrs.o
|
|
||||||
del %objpath%\BSOD.o
|
|
||||||
%nasm_path%\nasm.exe -f aout -o %objpath%/isrs_asm.o isrs.asm
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/isrs.o isrs.c
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/BSOD.o BSOD.c
|
|
||||||
if not exist %objpath%\isrs_asm.o goto error
|
|
||||||
if not exist %objpath%\isrs.o goto error
|
|
||||||
if not exist %objpath%\BSOD.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
:keyboard
|
|
||||||
cd keyboard
|
|
||||||
@echo * Compiling KEYBOARD...
|
|
||||||
del %objpath%\keyus.o
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/keyus.o keyus.c
|
|
||||||
if not exist %objpath%\keyus.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
:pic
|
|
||||||
cd pic
|
|
||||||
@echo * Compiling Programmable Interrupt Controller...
|
|
||||||
del %objpath%\pic.o
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pic.o pic.c
|
|
||||||
if not exist %objpath%\pic.o goto error
|
|
||||||
cd..
|
|
||||||
|
|
||||||
:pit
|
|
||||||
cd pit
|
|
||||||
@echo * Compiling Programmable Interval Timer...
|
|
||||||
del %objpath%\pit.o
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pit.o pit.c
|
|
||||||
if not exist %objpath%\pit.o goto error
|
|
||||||
cd..
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pic.o pic.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef _PIC_H
|
|
||||||
#define _PIC_H
|
|
||||||
|
|
||||||
extern void i86_pic_remap(int pic1, int pic2);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
@echo off
|
|
||||||
rem The name of the loader assembly file (without extension, must be .asm):
|
|
||||||
set loader_name=loader
|
|
||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
|
||||||
set nasm_path=C:\nasm
|
|
||||||
set djgpp_path=C:\DJGPP\bin
|
|
||||||
set objpath=../../objects
|
|
||||||
set incpath=../../include
|
|
||||||
|
|
||||||
@echo on
|
|
||||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/pit.o pit.c
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
@echo .
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
@pause
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#include <system.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "../irq/irq.h"
|
|
||||||
#include "pit.h"
|
|
||||||
|
|
||||||
volatile unsigned int _pit_ticks = 0;
|
|
||||||
volatile unsigned int _pit_frequency = 0;
|
|
||||||
unsigned char _pit_init = 0;
|
|
||||||
volatile TIME _internal_clock;
|
|
||||||
|
|
||||||
|
|
||||||
void i86_pit_set_frequency(int frequency)
|
|
||||||
{
|
|
||||||
int divisor = 1193180/frequency; // Calculate the divisor
|
|
||||||
outportb(0x43, 0x36); // Set our command byte 0x36
|
|
||||||
outportb(0x40, divisor&0xFF); // Set low byte
|
|
||||||
outportb(0x40, divisor>>8); // Set high byte
|
|
||||||
_pit_frequency = frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
void i86_pit_handler(ISR_stack_regs *r)
|
|
||||||
{
|
|
||||||
_pit_ticks++; // count tick
|
|
||||||
if (_pit_ticks % _pit_frequency == 0)
|
|
||||||
_CLOCK_INC((TIME*)&_internal_clock); // update internal clock
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int i86_pit_set_tick_count(unsigned int i)
|
|
||||||
{
|
|
||||||
unsigned int r = _pit_ticks;
|
|
||||||
_pit_ticks = i;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int i86_pit_get_tick_count()
|
|
||||||
{
|
|
||||||
return _pit_ticks;
|
|
||||||
}
|
|
||||||
unsigned int i86_pit_get_frequency()
|
|
||||||
{
|
|
||||||
return _pit_frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
void i86_pit_install(int freq)
|
|
||||||
{
|
|
||||||
i86_irq_install_handler(0, i86_pit_handler);
|
|
||||||
i86_pit_set_frequency(freq);
|
|
||||||
_pit_ticks = 0;
|
|
||||||
_pit_init = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TIME i86_pit_get_time()
|
|
||||||
{
|
|
||||||
return _internal_clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char i86_pit_is_initialized()
|
|
||||||
{
|
|
||||||
return _pit_init;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#ifndef __PIT_H
|
|
||||||
#define __PIT_H
|
|
||||||
|
|
||||||
#include<regs.h>
|
|
||||||
extern volatile unsigned int _pit_ticks;
|
|
||||||
extern volatile unsigned int _pit_frequency;
|
|
||||||
extern volatile TIME _internal_clock;
|
|
||||||
|
|
||||||
extern void i86_pit_handler(ISR_stack_regs *r);
|
|
||||||
extern void i86_pit_set_frequency(int frequency);
|
|
||||||
extern unsigned int i86_pit_set_tick_count(unsigned int i);
|
|
||||||
extern unsigned int i86_pit_get_tick_count();
|
|
||||||
extern unsigned int i86_pit_get_frequency();
|
|
||||||
extern void i86_pit_install(int freq);
|
|
||||||
extern unsigned char i86_pit_is_initialized();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/***** floppy.h ******************************************************
|
||||||
|
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||||
|
* *
|
||||||
|
* Floppy Drive I/O Routines *
|
||||||
|
* ========================= *
|
||||||
|
* *
|
||||||
|
************************************************************ cta os */
|
||||||
|
#include<regs.h>
|
||||||
|
|
||||||
|
extern unsigned char FloppyInitializeDMA(unsigned char* buffer, unsigned length);
|
||||||
|
extern void FloppyMotor (unsigned char drive, unsigned char on);
|
||||||
|
extern void i86_FloppyHandler(ISR_stack_regs *r);
|
||||||
|
extern void FloppyDriveData (unsigned char drv, unsigned char dma);
|
||||||
|
extern unsigned char FloppyCalibrate(unsigned drive);
|
||||||
|
extern void FloppyReset();
|
||||||
|
|
||||||
|
extern unsigned char FloppySeek (unsigned drive, unsigned cyl, unsigned head);
|
||||||
|
extern void FloppyInstall();
|
||||||
|
extern unsigned char FloppyIsDriverEnabled();
|
||||||
|
|
||||||
|
// Read/Write routines
|
||||||
|
extern unsigned* FloppyReadSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count);
|
||||||
|
extern unsigned* FloppyWriteSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count);
|
||||||
|
|
||||||
|
extern void FloppyReadSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector);
|
||||||
|
extern void FloppyWritedSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector);
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
#ifndef __KEYBOARD_H
|
||||||
|
#define __KEYBOARD_H
|
||||||
|
|
||||||
|
#include <regs.h>
|
||||||
|
|
||||||
|
#define KeyboardKeyModifierLeftShift 0x81 // 1000 0001
|
||||||
|
#define KeyboardKeyModifierRightShift 0x82 // 1000 0010
|
||||||
|
#define KeyboardKeyModifierLeftAlt 0x84 // 1000 0100
|
||||||
|
#define KeyboardKeyModifierRightAlt 0x88 // 1000 1000
|
||||||
|
#define KeyboardKeyModifierLeftCtrl 0x90 // 1001 0000
|
||||||
|
#define KeyboardKeyModifierRightCtrl 0xA0 // 1010 0000
|
||||||
|
#define KeyboardKeyFakeShift 0xC0 // 1100 0000
|
||||||
|
|
||||||
|
#define KeyboardLightScroll 0xF1 // 1111 0001
|
||||||
|
#define KeyboardLightNum 0xF2 // 1111 0010
|
||||||
|
#define KeyboardLightCaps 0xF4 // 1111 0100
|
||||||
|
|
||||||
|
|
||||||
|
enum KeyboardKeys {
|
||||||
|
KeyboardKeyPause = 0x00,
|
||||||
|
KeyboardKeyF9 = 0x01,
|
||||||
|
KeyboardKeyF7 = 0x02,
|
||||||
|
KeyboardKeyF5 = 0X03,
|
||||||
|
KeyboardKeyF3 = 0x04,
|
||||||
|
KeyboardKeyF1 = 0x05,
|
||||||
|
KeyboardKeyF2 = 0x06,
|
||||||
|
KeyboardKeyF12 = 0x07,
|
||||||
|
KeyboardKeyPrintScreen = 0x08,
|
||||||
|
KeyboardKeyF10 = 0x09,
|
||||||
|
KeyboardKeyF8 = 0x0A,
|
||||||
|
KeyboardKeyF6 = 0x0B,
|
||||||
|
KeyboardKeyF4 = 0x0C,
|
||||||
|
KeyboardKeyTab = 0x0D,
|
||||||
|
KeyboardKeyTilda = 0x0E,
|
||||||
|
KeyboardKeyQ = 0x15,
|
||||||
|
KeyboardKey1 = 0x16,
|
||||||
|
KeyboardKeyZ = 0x1A,
|
||||||
|
KeyboardKeyS = 0x1B,
|
||||||
|
KeyboardKeyA = 0x1C,
|
||||||
|
KeyboardKeyW = 0x1D,
|
||||||
|
KeyboardKey2 = 0x1E,
|
||||||
|
KeyboardKeyLeftWin = 0x1F,
|
||||||
|
KeyboardKeyC = 0x21,
|
||||||
|
KeyboardKeyX = 0x22,
|
||||||
|
KeyboardKeyD = 0x23,
|
||||||
|
KeyboardKeyE = 0x24,
|
||||||
|
KeyboardKey4 = 0x25,
|
||||||
|
KeyboardKey3 = 0x26,
|
||||||
|
KeyboardKeyRightWin = 0x27,
|
||||||
|
KeyboardKeySpace = 0x29,
|
||||||
|
KeyboardKeyV = 0x2A,
|
||||||
|
KeyboardKeyF = 0x2B,
|
||||||
|
KeyboardKeyT = 0x2C,
|
||||||
|
KeyboardKeyR = 0x2D,
|
||||||
|
KeyboardKey5 = 0x2E,
|
||||||
|
KeyboardKeyMenu = 0x2F,
|
||||||
|
KeyboardKeyN = 0x31,
|
||||||
|
KeyboardKeyB = 0x32,
|
||||||
|
KeyboardKeyH = 0x33,
|
||||||
|
KeyboardKeyG = 0x34,
|
||||||
|
KeyboardKeyY = 0x35,
|
||||||
|
KeyboardKey6 = 0x36,
|
||||||
|
KeyboardKeyM = 0x3A,
|
||||||
|
KeyboardKeyJ = 0x3B,
|
||||||
|
KeyboardKeyU = 0x3C,
|
||||||
|
KeyboardKey7 = 0x3D,
|
||||||
|
KeyboardKey8 = 0x3E,
|
||||||
|
KeyboardKeyComma = 0x41,
|
||||||
|
KeyboardKeyK = 0x42,
|
||||||
|
KeyboardKeyI = 0x43,
|
||||||
|
KeyboardKeyO = 0x44,
|
||||||
|
KeyboardKey0 = 0x45,
|
||||||
|
KeyboardKey9 = 0x46,
|
||||||
|
KeyboardKeyPeriod = 0x49,
|
||||||
|
KeyboardKeySlash = 0x4A,
|
||||||
|
KeyboardKeyL = 0x4B,
|
||||||
|
KeyboardKeySemicolon = 0x4C,
|
||||||
|
KeyboardKeyP = 0x4D,
|
||||||
|
KeyboardKeyDash = 0x4E,
|
||||||
|
KeyboardKeyApostrophe = 0x52,
|
||||||
|
KeyboardKeyLeftBracket = 0x54,
|
||||||
|
KeyboardKeyEqual = 0x55,
|
||||||
|
KeyboardKeyNumpadEnter = 0x59,
|
||||||
|
KeyboardKeyReturn = 0x5A,
|
||||||
|
KeyboardKeyRightBracket = 0x5B,
|
||||||
|
KeyboardKeyBackSlash = 0x5D,
|
||||||
|
KeyboardKeyEnd = 0x5E,
|
||||||
|
KeyboardKeyLeft = 0x5F,
|
||||||
|
KeyboardKeyHome = 0x60,
|
||||||
|
KeyboardKeyInsert = 0x61,
|
||||||
|
KeyboardKeyDelete = 0x62,
|
||||||
|
KeyboardKeyDown = 0x63,
|
||||||
|
KeyboardKeyRight = 0x64,
|
||||||
|
KeyboardKeyUp = 0x65,
|
||||||
|
KeyboardKeyBackspace = 0x66,
|
||||||
|
KeyboardKeyPageDown = 0x67,
|
||||||
|
KeyboardKeyPageUp = 0x68,
|
||||||
|
KeyboardKeyNumpad1 = 0x69,
|
||||||
|
KeyboardKeyNumpadSlash = 0x6A,
|
||||||
|
KeyboardKeyNumpad4 = 0x6B,
|
||||||
|
KeyboardKeyNumpad7 = 0x6C,
|
||||||
|
KeyboardKeyNumpad0 = 0x70,
|
||||||
|
KeyboardKeyNumpadColon = 0x71,
|
||||||
|
KeyboardKeyNumpad2 = 0x72,
|
||||||
|
KeyboardKeyNumpad5 = 0x73,
|
||||||
|
KeyboardKeyNumpad6 = 0x74,
|
||||||
|
KeyboardKeyNumpad8 = 0x75,
|
||||||
|
KeyboardKeyEscape = 0x76,
|
||||||
|
KeyboardKeyF11 = 0x78,
|
||||||
|
KeyboardKeyNumpadPlus = 0x79,
|
||||||
|
KeyboardKeyNumpad3 = 0x7A,
|
||||||
|
KeyboardKeyNumpadMinus = 0x7B,
|
||||||
|
KeyboardKeyNumpadAsterisk = 0x7C,
|
||||||
|
KeyboardKeyNumpad9 = 0x7D
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char ModifierStatus;
|
||||||
|
unsigned char Lights;
|
||||||
|
unsigned char Scancode;
|
||||||
|
unsigned char Character;
|
||||||
|
} KeyboardKey;
|
||||||
|
|
||||||
|
extern void KeyboardSetKey(unsigned char scancode, unsigned char val);
|
||||||
|
extern unsigned char KeyIsPressed(unsigned char scancode);
|
||||||
|
extern void i86_KeyboardHandler(ISR_stack_regs *r);
|
||||||
|
extern KeyboardKey GetKey();
|
||||||
|
|
||||||
|
/**\n
|
||||||
|
Sets the repeat rate/delay\n
|
||||||
|
\n\Delay:
|
||||||
|
Values for inter-character delay (bits 4-0)\n
|
||||||
|
(characters per second; default is 10.9)\n
|
||||||
|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 \n
|
||||||
|
----+----+----+----+----+----+----+----+----\n
|
||||||
|
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0\n
|
||||||
|
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0\n
|
||||||
|
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0\n
|
||||||
|
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0\n
|
||||||
|
\n
|
||||||
|
Values for delay:\n
|
||||||
|
(miliseconds; default is 500)\n
|
||||||
|
0 | 1 | 2 | 3\n
|
||||||
|
-----+-----+-----+-----\n
|
||||||
|
250 | 500 | 750 | 1000\n \n*/
|
||||||
|
extern void KeyboardSetRepeatRate(unsigned char rate, unsigned char delay);
|
||||||
|
|
||||||
|
/***************************************
|
||||||
|
* Set keyboard LEDs *
|
||||||
|
***************************************
|
||||||
|
+-----------+-------+-------+--------+
|
||||||
|
| Bits 7-3 | Bit 2 | Bit 1 | Bit 0 |
|
||||||
|
| 0 | Caps | Num | Scroll |
|
||||||
|
|(reserved) | lock | lock | lock |
|
||||||
|
+-----------+-------+-------+--------+
|
||||||
|
***************************************/
|
||||||
|
extern void KeyboardSetLEDs(unsigned char status);
|
||||||
|
|
||||||
|
/***************************************
|
||||||
|
* Set scancode set *
|
||||||
|
***************************************
|
||||||
|
0 Get current scancode set
|
||||||
|
1 Set to scancode set 1
|
||||||
|
2 Set to scancode set 2
|
||||||
|
3 Set to scancode set 3
|
||||||
|
***************************************/
|
||||||
|
extern void KeyboardSetScancodeSet(unsigned char set);
|
||||||
|
extern void KeyboardWaitInput();
|
||||||
|
extern void KeyboardWaitOutput();
|
||||||
|
extern void KeyboardInstallA();
|
||||||
|
extern void KeyboardInstallB();
|
||||||
|
|
||||||
|
#endif
|
||||||
+113
-130
@@ -10,7 +10,7 @@
|
|||||||
#define i86_start_interrupts() __asm__ __volatile__ ("sti");
|
#define i86_start_interrupts() __asm__ __volatile__ ("sti");
|
||||||
#define i86_clear_interrupts() __asm__ __volatile__ ("cli");
|
#define i86_clear_interrupts() __asm__ __volatile__ ("cli");
|
||||||
|
|
||||||
extern TIME i86_pit_get_time() ;
|
extern TIME ClockGetTime() ;
|
||||||
extern unsigned* i86_read_sector (unsigned* where, unsigned char drive, int sectorLBA);
|
extern unsigned* i86_read_sector (unsigned* where, unsigned char drive, int sectorLBA);
|
||||||
// initialize hardware abstraction layer
|
// initialize hardware abstraction layer
|
||||||
extern void i86_hal_initialize ();
|
extern void i86_hal_initialize ();
|
||||||
@@ -39,146 +39,129 @@ extern void sound (unsigned frequency);
|
|||||||
//! returns cpu vender
|
//! returns cpu vender
|
||||||
extern const char* get_cpu_vender ();
|
extern const char* get_cpu_vender ();
|
||||||
|
|
||||||
extern void reboot();
|
extern void SystemReboot();
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* KEYBOARD STUFF *
|
* KEYBOARD STUFF *
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#define KB_KEY_LSHIFT 0x81 // 1000 0001
|
#define KeyboardKeyModifierLeftShift 0x81 // 1000 0001
|
||||||
#define KB_KEY_RSHIFT 0X82 // 1000 0010
|
#define KeyboardKeyModifierRightShift 0x82 // 1000 0010
|
||||||
#define KB_KEY_LALT 0X84 // 1000 0100
|
#define KeyboardKeyModifierLeftAlt 0x84 // 1000 0100
|
||||||
#define KB_KEY_RALT 0x88 // 1000 1000
|
#define KeyboardKeyModifierRightAlt 0x88 // 1000 1000
|
||||||
#define KB_KEY_LCTRL 0x90 // 1001 0000
|
#define KeyboardKeyModifierLeftCtrl 0x90 // 1001 0000
|
||||||
#define KB_KEY_RCTRL 0xA0 // 1010 0000
|
#define KeyboardKeyModifierRightCtrl 0xA0 // 1010 0000
|
||||||
#define KB_KEY_FSHIFT 0xC0 // 1100 0000
|
#define KeyboardKeyFakeShift 0xC0 // 1100 0000
|
||||||
extern volatile unsigned char kb_modifier_status;
|
|
||||||
|
|
||||||
#define KB_PREFIX_GRAY 0x01 // Gray
|
#define KeyboardLightScroll 0xF1 // 1111 0001
|
||||||
#define KB_PREFIX_BREAK 0x02 // Break code
|
#define KeyboardLightNum 0xF2 // 1111 0010
|
||||||
#define KB_PREFIX_PAUSE 0x04 // Pause/break key
|
#define KeyboardLightCaps 0xF4 // 1111 0100
|
||||||
#define KB_PREFIX_PAUSE1 0x08 // Recieved first unsigned char from pause/break
|
|
||||||
extern volatile unsigned char kb_prefix;
|
|
||||||
|
|
||||||
#define KB_KEY_SCROLL 0xF1 // 1111 0001
|
enum KeyboardKeys {
|
||||||
#define KB_KEY_NUM 0xF2 // 1111 0010
|
KeyboardKeyPause = 0x00,
|
||||||
#define KB_KEY_CAPS 0xF4 // 1111 0100
|
KeyboardKeyF9 = 0x01,
|
||||||
extern volatile unsigned char kb_lights_status;
|
KeyboardKeyF7 = 0x02,
|
||||||
|
KeyboardKeyF5 = 0X03,
|
||||||
extern unsigned char kb_scancode_set;
|
KeyboardKeyF3 = 0x04,
|
||||||
|
KeyboardKeyF1 = 0x05,
|
||||||
enum KB_KEYS {
|
KeyboardKeyF2 = 0x06,
|
||||||
KB_KEY_PAUSE = 0x00,
|
KeyboardKeyF12 = 0x07,
|
||||||
KB_KEY_F9 = 0x01,
|
KeyboardKeyPrintScreen = 0x08,
|
||||||
KB_KEY_F7 = 0x02,
|
KeyboardKeyF10 = 0x09,
|
||||||
KB_KEY_F5 = 0X03,
|
KeyboardKeyF8 = 0x0A,
|
||||||
KB_KEY_F3 = 0x04,
|
KeyboardKeyF6 = 0x0B,
|
||||||
KB_KEY_F1 = 0x05,
|
KeyboardKeyF4 = 0x0C,
|
||||||
KB_KEY_F2 = 0x06,
|
KeyboardKeyTab = 0x0D,
|
||||||
KB_KEY_F12 = 0x07,
|
KeyboardKeyTilda = 0x0E,
|
||||||
KB_KEY_PRINTSCRN = 0x08,
|
KeyboardKeyQ = 0x15,
|
||||||
KB_KEY_F10 = 0x09,
|
KeyboardKey1 = 0x16,
|
||||||
KB_KEY_F8 = 0x0A,
|
KeyboardKeyZ = 0x1A,
|
||||||
KB_KEY_F6 = 0x0B,
|
KeyboardKeyS = 0x1B,
|
||||||
KB_KEY_F4 = 0x0C,
|
KeyboardKeyA = 0x1C,
|
||||||
KB_KEY_TAB = 0x0D,
|
KeyboardKeyW = 0x1D,
|
||||||
KB_KEY_TILDA = 0x0E,
|
KeyboardKey2 = 0x1E,
|
||||||
KB_KEY_Q = 0x15,
|
KeyboardKeyLeftWin = 0x1F,
|
||||||
KB_KEY_1 = 0x16,
|
KeyboardKeyC = 0x21,
|
||||||
KB_KEY_Z = 0x1A,
|
KeyboardKeyX = 0x22,
|
||||||
KB_KEY_S = 0x1B,
|
KeyboardKeyD = 0x23,
|
||||||
KB_KEY_A = 0x1C,
|
KeyboardKeyE = 0x24,
|
||||||
KB_KEY_W = 0x1D,
|
KeyboardKey4 = 0x25,
|
||||||
KB_KEY_2 = 0x1E,
|
KeyboardKey3 = 0x26,
|
||||||
KB_KEY_LWIN = 0x1F,
|
KeyboardKeyRightWin = 0x27,
|
||||||
KB_KEY_C = 0x21,
|
KeyboardKeySpace = 0x29,
|
||||||
KB_KEY_X = 0x22,
|
KeyboardKeyV = 0x2A,
|
||||||
KB_KEY_D = 0x23,
|
KeyboardKeyF = 0x2B,
|
||||||
KB_KEY_E = 0x24,
|
KeyboardKeyT = 0x2C,
|
||||||
KB_KEY_4 = 0x25,
|
KeyboardKeyR = 0x2D,
|
||||||
KB_KEY_3 = 0x26,
|
KeyboardKey5 = 0x2E,
|
||||||
KB_KEY_RWIN = 0x27,
|
KeyboardKeyMenu = 0x2F,
|
||||||
KB_KEY_SPACE = 0x29,
|
KeyboardKeyN = 0x31,
|
||||||
KB_KEY_V = 0x2A,
|
KeyboardKeyB = 0x32,
|
||||||
KB_KEY_F = 0x2B,
|
KeyboardKeyH = 0x33,
|
||||||
KB_KEY_T = 0x2C,
|
KeyboardKeyG = 0x34,
|
||||||
KB_KEY_R = 0x2D,
|
KeyboardKeyY = 0x35,
|
||||||
KB_KEY_5 = 0x2E,
|
KeyboardKey6 = 0x36,
|
||||||
KB_KEY_MENU = 0x2F,
|
KeyboardKeyM = 0x3A,
|
||||||
KB_KEY_N = 0x31,
|
KeyboardKeyJ = 0x3B,
|
||||||
KB_KEY_B = 0x32,
|
KeyboardKeyU = 0x3C,
|
||||||
KB_KEY_H = 0x33,
|
KeyboardKey7 = 0x3D,
|
||||||
KB_KEY_G = 0x34,
|
KeyboardKey8 = 0x3E,
|
||||||
KB_KEY_Y = 0x35,
|
KeyboardKeyComma = 0x41,
|
||||||
KB_KEY_6 = 0x36,
|
KeyboardKeyK = 0x42,
|
||||||
KB_KEY_M = 0x3A,
|
KeyboardKeyI = 0x43,
|
||||||
KB_KEY_J = 0x3B,
|
KeyboardKeyO = 0x44,
|
||||||
KB_KEY_U = 0x3C,
|
KeyboardKey0 = 0x45,
|
||||||
KB_KEY_7 = 0x3D,
|
KeyboardKey9 = 0x46,
|
||||||
KB_KEY_8 = 0x3E,
|
KeyboardKeyPeriod = 0x49,
|
||||||
KB_KEY_COMMA = 0x41,
|
KeyboardKeySlash = 0x4A,
|
||||||
KB_KEY_K = 0x42,
|
KeyboardKeyL = 0x4B,
|
||||||
KB_KEY_I = 0x43,
|
KeyboardKeySemicolon = 0x4C,
|
||||||
KB_KEY_O = 0x44,
|
KeyboardKeyP = 0x4D,
|
||||||
KB_KEY_0 = 0x45,
|
KeyboardKeyDash = 0x4E,
|
||||||
KB_KEY_9 = 0x46,
|
KeyboardKeyApostrophe = 0x52,
|
||||||
KB_KEY_PERIOD = 0x49,
|
KeyboardKeyLeftBracket = 0x54,
|
||||||
KB_KEY_SLASH = 0x4A,
|
KeyboardKeyEqual = 0x55,
|
||||||
KB_KEY_L = 0x4B,
|
KeyboardKeyNumpadEnter = 0x59,
|
||||||
KB_KEY_SEMICOLON = 0x4C,
|
KeyboardKeyReturn = 0x5A,
|
||||||
KB_KEY_P = 0x4D,
|
KeyboardKeyRightBracket = 0x5B,
|
||||||
KB_KEY_DASH = 0x4E,
|
KeyboardKeyBackSlash = 0x5D,
|
||||||
KB_KEY_APOSTROPHE = 0x52,
|
KeyboardKeyEnd = 0x5E,
|
||||||
KB_KEY_LBRACKET = 0x54,
|
KeyboardKeyLeft = 0x5F,
|
||||||
KB_KEY_EQUAL = 0x55,
|
KeyboardKeyHome = 0x60,
|
||||||
KB_KEY_NUMPAD_ENTER = 0x59,
|
KeyboardKeyInsert = 0x61,
|
||||||
KB_KEY_ENTER = 0x5A,
|
KeyboardKeyDelete = 0x62,
|
||||||
KB_KEY_RBRACKET = 0x5B,
|
KeyboardKeyDown = 0x63,
|
||||||
KB_KEY_BACKSLASH = 0x5D,
|
KeyboardKeyRight = 0x64,
|
||||||
KB_KEY_END = 0x5E,
|
KeyboardKeyUp = 0x65,
|
||||||
KB_KEY_LEFT = 0x5F,
|
KeyboardKeyBackspace = 0x66,
|
||||||
KB_KEY_HOME = 0x60,
|
KeyboardKeyPageDown = 0x67,
|
||||||
KB_KEY_INSERT = 0x61,
|
KeyboardKeyPageUp = 0x68,
|
||||||
KB_KEY_DELETE = 0x62,
|
KeyboardKeyNumpad1 = 0x69,
|
||||||
KB_KEY_DOWN = 0x63,
|
KeyboardKeyNumpadSlash = 0x6A,
|
||||||
KB_KEY_RIGHT = 0x64,
|
KeyboardKeyNumpad4 = 0x6B,
|
||||||
KB_KEY_UP = 0x65,
|
KeyboardKeyNumpad7 = 0x6C,
|
||||||
KB_KEY_BACKSPACE = 0x66,
|
KeyboardKeyNumpad0 = 0x70,
|
||||||
KB_KEY_PGDOWN = 0x67,
|
KeyboardKeyNumpadColon = 0x71,
|
||||||
KB_KEY_PGUP = 0x68,
|
KeyboardKeyNumpad2 = 0x72,
|
||||||
KB_KEY_NUMPAD_1 = 0x69,
|
KeyboardKeyNumpad5 = 0x73,
|
||||||
KB_KEY_NUMPAD_SLASH = 0x6A,
|
KeyboardKeyNumpad6 = 0x74,
|
||||||
KB_KEY_NUMPAD_4 = 0x6B,
|
KeyboardKeyNumpad8 = 0x75,
|
||||||
KB_KEY_NUMPAD_7 = 0x6C,
|
KeyboardKeyEscape = 0x76,
|
||||||
KB_KEY_NUMPAD_0 = 0x70,
|
KeyboardKeyF11 = 0x78,
|
||||||
KB_KEY_NUMPAD_COLON = 0x71,
|
KeyboardKeyNumpadPlus = 0x79,
|
||||||
KB_KEY_NUMPAD_2 = 0x72,
|
KeyboardKeyNumpad3 = 0x7A,
|
||||||
KB_KEY_NUMPAD_5 = 0x73,
|
KeyboardKeyNumpadMinus = 0x7B,
|
||||||
KB_KEY_NUMPAD_6 = 0x74,
|
KeyboardKeyNumpadAsterisk = 0x7C,
|
||||||
KB_KEY_NUMPAD_8 = 0x75,
|
KeyboardKeyNumpad9 = 0x7D
|
||||||
KB_KEY_ESC = 0x76,
|
|
||||||
KB_KEY_F11 = 0x78,
|
|
||||||
KB_KEY_NUMPAD_PLUS = 0x79,
|
|
||||||
KB_KEY_NUMPAD_3 = 0x7A,
|
|
||||||
KB_KEY_NUMPAD_MINUS = 0x7B,
|
|
||||||
KB_KEY_NUMPAD_ASTERISK = 0x7C,
|
|
||||||
KB_KEY_NUMPAD_9 = 0x7D
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char status;
|
unsigned char ModifierStatus;
|
||||||
unsigned char lights;
|
unsigned char Lights;
|
||||||
unsigned char scancode;
|
unsigned char Scancode;
|
||||||
unsigned char character;
|
unsigned char Character;
|
||||||
} kb_key;
|
} KeyboardKey;
|
||||||
|
|
||||||
|
|
||||||
//extern char getch();
|
|
||||||
extern kb_key getkey();
|
|
||||||
extern char scancode_to_ascii(unsigned char scancode, unsigned char status);
|
|
||||||
extern unsigned char get_key_status(unsigned char scancode);
|
|
||||||
extern void kb_set_repeat(float rate, int delay);
|
|
||||||
extern void kb_set_LEDs(unsigned char status);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -18,6 +18,8 @@ typedef struct {
|
|||||||
|
|
||||||
extern void _CLOCK_INC(TIME *tim);
|
extern void _CLOCK_INC(TIME *tim);
|
||||||
|
|
||||||
|
#include "../drivers/clock/clock.h"
|
||||||
|
|
||||||
//extern char* asctime (TIME time);
|
//extern char* asctime (TIME time);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
rem NASM and DJGPP executable paths:
|
rem NASM and DJGPP executable paths:
|
||||||
set nasm_path=C:\nasm
|
set nasm_path=C:\nasm
|
||||||
set djgpp_path=C:\DJGPP\bin
|
set djgpp_path=C:\mingw\bin
|
||||||
set objpath=..\objects
|
set objpath=..\objects
|
||||||
set incpath=../include
|
set incpath=../include
|
||||||
|
|
||||||
|
|||||||
+29
-28
@@ -1,6 +1,6 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
#include <hal.h>
|
#include <drivers/keyboard.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -25,6 +25,7 @@ UPoint ScreenSize, Cursor;
|
|||||||
|
|
||||||
void ConsoleInstall(ConsoleScreen screen)
|
void ConsoleInstall(ConsoleScreen screen)
|
||||||
{
|
{
|
||||||
|
|
||||||
_console_cursor = screen.cursor;
|
_console_cursor = screen.cursor;
|
||||||
_console_putc = screen.putc;
|
_console_putc = screen.putc;
|
||||||
_console_getc = screen.getc;
|
_console_getc = screen.getc;
|
||||||
@@ -199,7 +200,7 @@ int cgets(char* string, int maxlen)
|
|||||||
memset ((void*)string, 0, maxlen);
|
memset ((void*)string, 0, maxlen);
|
||||||
|
|
||||||
int Len = 0, CurPos = 0;
|
int Len = 0, CurPos = 0;
|
||||||
kb_key Key;
|
KeyboardKey Key;
|
||||||
UPoint CursorSave;
|
UPoint CursorSave;
|
||||||
|
|
||||||
while (Len < maxlen)
|
while (Len < maxlen)
|
||||||
@@ -216,38 +217,38 @@ int cgets(char* string, int maxlen)
|
|||||||
Cursor = CursorSave;
|
Cursor = CursorSave;
|
||||||
|
|
||||||
// Get key and process
|
// Get key and process
|
||||||
Key = getkey();
|
Key = GetKey();
|
||||||
|
|
||||||
switch (Key.scancode) {
|
switch (Key.Scancode) {
|
||||||
// Switch overwrite/insert
|
// Switch overwrite/insert
|
||||||
case KB_KEY_INSERT: __cgets__key_insert(); break;
|
case KeyboardKeyInsert: __cgets__key_insert(); break;
|
||||||
|
|
||||||
// Finish writing (return)
|
// Finish writing (return)
|
||||||
case KB_KEY_ENTER: __cgets__key_enter(); break;
|
case KeyboardKeyReturn: __cgets__key_enter(); break;
|
||||||
case KB_KEY_NUMPAD_ENTER: __cgets__key_enter(); break;
|
case KeyboardKeyNumpadEnter: __cgets__key_enter(); break;
|
||||||
|
|
||||||
// Left
|
// Left
|
||||||
case KB_KEY_LEFT:
|
case KeyboardKeyLeft:
|
||||||
__cgets__move_cursor(string, 0, Len, &CurPos, ((Key.status & KB_KEY_LCTRL) || (Key.status & KB_KEY_RCTRL)));
|
__cgets__move_cursor(string, 0, Len, &CurPos, ((Key.ModifierStatus & KeyboardKeyModifierLeftCtrl) || (Key.ModifierStatus & KeyboardKeyModifierRightCtrl)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Right
|
// Right
|
||||||
case KB_KEY_RIGHT:
|
case KeyboardKeyRight:
|
||||||
__cgets__move_cursor(string, 1, Len, &CurPos, ((Key.status & KB_KEY_LCTRL) || (Key.status & KB_KEY_RCTRL)));
|
__cgets__move_cursor(string, 1, Len, &CurPos, ((Key.ModifierStatus & KeyboardKeyModifierLeftCtrl) || (Key.ModifierStatus & KeyboardKeyModifierRightCtrl)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KB_KEY_HOME:
|
case KeyboardKeyHome:
|
||||||
CurPos = 0;
|
CurPos = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KB_KEY_END:
|
case KeyboardKeyEnd:
|
||||||
CurPos = Len;
|
CurPos = Len;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KB_KEY_BACKSPACE:
|
case KeyboardKeyBackspace:
|
||||||
if (CurPos > 0) {
|
if (CurPos > 0) {
|
||||||
int tmp;
|
int tmp;
|
||||||
if ((Key.status & KB_KEY_LCTRL) || (Key.status & KB_KEY_RCTRL))
|
if ((Key.ModifierStatus & KeyboardKeyModifierLeftCtrl) || (Key.ModifierStatus & KeyboardKeyModifierRightCtrl))
|
||||||
tmp = __cgets__skip_word(string, Len, CurPos, 0);
|
tmp = __cgets__skip_word(string, Len, CurPos, 0);
|
||||||
else tmp = CurPos-1;
|
else tmp = CurPos-1;
|
||||||
|
|
||||||
@@ -258,11 +259,11 @@ int cgets(char* string, int maxlen)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
case KB_KEY_DELETE:
|
case KeyboardKeyDelete:
|
||||||
if (CurPos < Len) {
|
if (CurPos < Len) {
|
||||||
int tmp;
|
int tmp;
|
||||||
// If CTRL is pressed, foward one word
|
// If CTRL is pressed, foward one word
|
||||||
if ((Key.status & KB_KEY_LCTRL) || (Key.status & KB_KEY_RCTRL))
|
if ((Key.ModifierStatus & KeyboardKeyModifierLeftCtrl) || (Key.ModifierStatus & KeyboardKeyModifierRightCtrl))
|
||||||
tmp = __cgets__skip_word(string, Len, CurPos, 1);
|
tmp = __cgets__skip_word(string, Len, CurPos, 1);
|
||||||
else tmp = CurPos+1;
|
else tmp = CurPos+1;
|
||||||
|
|
||||||
@@ -274,22 +275,22 @@ int cgets(char* string, int maxlen)
|
|||||||
|
|
||||||
// Text character
|
// Text character
|
||||||
default:
|
default:
|
||||||
if (isprint(Key.character)) {
|
if (isprint(Key.Character)) {
|
||||||
// fix CAPS bug
|
// fix CAPS bug
|
||||||
if ((Key.lights & KB_KEY_CAPS) && islower((unsigned char)Key.character))
|
if ((Key.Lights & KeyboardLightCaps) && islower((unsigned char)Key.Character))
|
||||||
Key.character = toupper(Key.character);
|
Key.Character = toupper(Key.Character);
|
||||||
|
|
||||||
// Cursor is at the end of the string
|
// Cursor is at the end of the string
|
||||||
if (CurPos == Len) {
|
if (CurPos == Len) {
|
||||||
Len++; string[Len-1] = Key.character;
|
Len++; string[Len-1] = Key.Character;
|
||||||
string[Len] = 0;
|
string[Len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cursor is not at the end in OverWrite mode
|
// Cursor is not at the end in OverWrite mode
|
||||||
else if (OverWrite) string[CurPos] = Key.character;
|
else if (OverWrite) string[CurPos] = Key.Character;
|
||||||
|
|
||||||
// Cursor is not at the end in Insert mode
|
// Cursor is not at the end in Insert mode
|
||||||
else __cgets__insert(string, CurPos, Key.character, &Len);
|
else __cgets__insert(string, CurPos, Key.Character, &Len);
|
||||||
|
|
||||||
// Increase cursor position
|
// Increase cursor position
|
||||||
CurPos++;
|
CurPos++;
|
||||||
@@ -361,13 +362,13 @@ int cputs(const char* str)
|
|||||||
|
|
||||||
int getch()
|
int getch()
|
||||||
{
|
{
|
||||||
kb_key k;
|
KeyboardKey k;
|
||||||
k = getkey();
|
k = GetKey();
|
||||||
|
|
||||||
if ((k.lights & KB_KEY_CAPS) && k.character >= 'a' && k.character <= 'z')
|
if ((k.Lights & KeyboardLightCaps) && k.Character >= 'a' && k.Character <= 'z')
|
||||||
return (int)(k.character - 'a' + 'A');
|
return (int)(k.Character - 'a' + 'A');
|
||||||
|
|
||||||
return k.character;
|
return k.Character;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user