185 lines
4.6 KiB
C
185 lines
4.6 KiB
C
#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"
|
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
// 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");
|
|
}
|
|
|
|
//! notifies hal interrupt is done
|
|
/*inline void interruptdone (unsigned int intno) {
|
|
|
|
//! insure its a valid hardware irq
|
|
if (intno > 16)
|
|
return;
|
|
|
|
//! test if we need to send end-of-interrupt to second pic
|
|
if (intno >= 8)
|
|
i86_pic_send_command (0x20, 0xA1);
|
|
|
|
//! always send end-of-interrupt to primary pic
|
|
i86_pic_send_command (0x20, 0x21);
|
|
}
|
|
*/
|
|
|
|
//! output sound to speaker
|
|
void sound (unsigned frequency) {
|
|
|
|
//! sets frequency for speaker. frequency of 0 disables speaker
|
|
outportb (0x61, 3 | (byte)(frequency<<2) );
|
|
}
|
|
|
|
|
|
|
|
|
|
//! sets new interrupt vector
|
|
/*void _cdecl setvect (int intno, void (_cdecl far &vect) ( ) ) {
|
|
|
|
//! install interrupt handler! This overwrites prev interrupt descriptor
|
|
i86_install_ir (intno, I86_IDT_DESC_PRESENT | I86_IDT_DESC_BIT32,
|
|
0x8, vect);
|
|
}
|
|
|
|
|
|
//! returns current interrupt vector
|
|
void (_cdecl far * _cdecl getvect (int intno)) ( ) {
|
|
|
|
//! get the descriptor from the idt
|
|
idt_descriptor* desc = i86_get_ir (intno);
|
|
if (!desc)
|
|
return 0;
|
|
|
|
//! get address of interrupt handler
|
|
uint32_t addr = desc->baseLo | (desc->baseHi << 16);
|
|
|
|
//! return interrupt handler
|
|
I86_IRQ_HANDLER irq = (I86_IRQ_HANDLER)addr;
|
|
return irq;
|
|
}
|
|
|
|
*/
|
|
//! returns cpu vender
|
|
const char* get_cpu_vender () {
|
|
|
|
return i86_cpu_get_vender();
|
|
}
|
|
|
|
|
|
/***************************************************************************************
|
|
* Keyboard Routines *
|
|
***************************************************************************************/
|
|
char getch()
|
|
{
|
|
kb_key alpha = getkey();
|
|
return alpha.character;
|
|
}
|
|
|
|
char scancode_to_ascii(byte scancode, byte status)
|
|
{
|
|
if ((status&1) || (status&2)) return kbdus_map_shift[scancode];
|
|
else return kbdus_map[scancode];
|
|
}
|
|
|
|
byte get_key_status (byte 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} ;
|
|
|
|
|
|
byte 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(byte status) {
|
|
i86_kb_set_LEDs(status);
|
|
}
|