summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-08-20 15:55:03 +0200
committerMichal Idziorek <m.i@gmx.at>2014-08-20 15:55:03 +0200
commitdc164927e71d760a41494ab1edf8e3deeda401db (patch)
tree65253b4a5e443c599341d5972b58449388a4b2b1
parent46063e75f3f81dfb532fa5772c88e9027a0faebd (diff)
started implementing floppy driver etc.
-rw-r--r--Makefile8
-rw-r--r--README.md4
-rw-r--r--boot/mbr.asm2
-rw-r--r--kernel/console.c1
-rw-r--r--kernel/floppy.c426
-rw-r--r--kernel/interrupts.c10
-rw-r--r--kernel/kernel.c24
-rw-r--r--kernel/kernel.h6
-rw-r--r--kernel/keyboard.c6
-rw-r--r--kernel/mem.c1
-rw-r--r--kernel/shell.c4
-rw-r--r--kernel/syslog.h6
-rw-r--r--kernel/timer.c17
-rw-r--r--kernel/x86.c38
-rw-r--r--kernel/x86.h43
15 files changed, 525 insertions, 71 deletions
diff --git a/Makefile b/Makefile
index ea79f44..125d957 100644
--- a/Makefile
+++ b/Makefile
@@ -32,6 +32,12 @@ kernel_entry.o: boot/kernel_entry.asm
kernel.o: kernel/kernel.c kernel/console.h
gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0
+x86.o: kernel/x86.c
+ gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0
+
+floppy.o: kernel/floppy.c
+ gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0
+
vmem.o: kernel/vmem.c
gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0
@@ -59,7 +65,7 @@ timer.o: kernel/timer.c
shell.o: kernel/shell.c
gcc -ffreestanding -m32 -o $@ -c $< -fno-asynchronous-unwind-tables -O0
-kernel.bin: kernel_entry.o kernel.o console.o interrupts.o keyboard.o timer.o shell.o mem.o vmem.o pci.o e1000.o
+kernel.bin: kernel_entry.o kernel.o console.o interrupts.o keyboard.o timer.o floppy.o x86.o shell.o mem.o vmem.o pci.o e1000.o
ld -o $@ -Ttext 0x1000 --oformat binary -melf_i386 $^ -O0
diff --git a/README.md b/README.md
index 1fce118..62a6560 100644
--- a/README.md
+++ b/README.md
@@ -28,8 +28,8 @@ Issues
* memory map may be larger than mbr, but 0x0000 is used to check for end.
* memory map location is hardcoded
-* ~4 first 4mb of physical mem are reserved by mem manager (hardcoded)
-* bootloader loads only 15sectors of kernel into mem. ~7KB?
+* the first ~4mb of physical mem are reserved by mem manager (hardcoded)
+* bootloader loads only 50 sectors of kernel into mem. 25KB!
* Makefile is hardcoded and contains some mistakes too!
* size of bitmap to track free blocks of physical memory is hardcoded to max.
* physical memory manager allocator naively implemented.
diff --git a/boot/mbr.asm b/boot/mbr.asm
index fd13a76..2d87c20 100644
--- a/boot/mbr.asm
+++ b/boot/mbr.asm
@@ -107,7 +107,7 @@ boot_16:
;Load the KERNEL
mov bx,KERNEL_OFFSET
- mov dh, 15
+ mov dh, 50
mov dl, [BOOT_DRIVE]
call disk_load
diff --git a/kernel/console.c b/kernel/console.c
index 77b5fc1..42dc5d0 100644
--- a/kernel/console.c
+++ b/kernel/console.c
@@ -99,6 +99,7 @@ void scr_nextline()
void scr_put_char(char ch,char col)
{
+
print_char_col(posx,posy,ch,SCR_WHITE);
posx++;
if(posx>=SCR_WIDTH)scr_nextline();
diff --git a/kernel/floppy.c b/kernel/floppy.c
new file mode 100644
index 0000000..2c71cdb
--- /dev/null
+++ b/kernel/floppy.c
@@ -0,0 +1,426 @@
+#include "x86.h"
+
+#define FLPY_SECTORS_PER_TRACK 80
+static volatile int _CurrentDrive=0;
+static volatile uint8_t _FloppyDiskIRQ = 0;
+
+// temporary dma hack
+//! initialize DMA to use phys addr 1k-64k
+void flpydsk_initialize_dma () {
+
+ scr_put_string_nl("dma: initialize direct memory access");
+ x86_outb (0x0a,0x06); //mask dma channel 2
+ x86_outb (0xd8,0xff); //reset master flip-flop
+
+ //changed to 0x000 (Address)
+ x86_outb (0x04, 0x0); //low
+ x86_outb (0x04, 0xa0); //high
+
+ x86_outb (0xd8, 0xff); //reset master flip-flop
+ x86_outb (0x05, 0xff); //count to 0x23ff (number of bytes in a 3.5" floppy disk track)
+ x86_outb (0x05, 0x23);
+ x86_outb (0x80, 0); //external page register = 0
+ x86_outb (0x0a, 0x02); //unmask dma channel 2
+}
+
+//! prepare the DMA for read transfer
+void flpydsk_dma_read () {
+
+ x86_outb (0x0a, 0x06); //mask dma channel 2
+ x86_outb (0x0b, 0x56); //single transfer, address increment, autoinit, read, channel 2
+ x86_outb (0x0a, 0x02); //unmask dma channel 2
+ scr_put_string_nl("dma: configured for reading");
+}
+
+//! prepare the DMA for write transfer
+void flpydsk_dma_write () {
+
+ x86_outb (0x0a, 0x06); //mask dma channel 2
+ x86_outb (0x0b, 0x5a); //single transfer, address increment, autoinit, write, channel 2
+ x86_outb (0x0a, 0x02); //unmask dma channel 2
+ scr_put_string_nl("dma: configured for writing");
+}
+//
+//
+
+enum FLPYDSK_IO {
+
+ FLPYDSK_DOR = 0x3f2,
+ FLPYDSK_MSR = 0x3f4,
+ FLPYDSK_FIFO = 0x3f5, //data register
+ FLPYDSK_CTRL = 0x3f7
+};
+
+enum FLPYDSK_DOR_MASK {
+
+ FLPYDSK_DOR_MASK_DRIVE0 = 0, //00000000 = here for completeness sake
+ FLPYDSK_DOR_MASK_DRIVE1 = 1, //00000001
+ FLPYDSK_DOR_MASK_DRIVE2 = 2, //00000010
+ FLPYDSK_DOR_MASK_DRIVE3 = 3, //00000011
+ FLPYDSK_DOR_MASK_RESET = 4, //00000100
+ FLPYDSK_DOR_MASK_DMA = 8, //00001000
+ FLPYDSK_DOR_MASK_DRIVE0_MOTOR = 16, //00010000
+ FLPYDSK_DOR_MASK_DRIVE1_MOTOR = 32, //00100000
+ FLPYDSK_DOR_MASK_DRIVE2_MOTOR = 64, //01000000
+ FLPYDSK_DOR_MASK_DRIVE3_MOTOR = 128 //10000000
+};
+
+enum FLPYDSK_MSR_MASK {
+
+ FLPYDSK_MSR_MASK_DRIVE1_POS_MODE = 1, //00000001
+ FLPYDSK_MSR_MASK_DRIVE2_POS_MODE = 2, //00000010
+ FLPYDSK_MSR_MASK_DRIVE3_POS_MODE = 4, //00000100
+ FLPYDSK_MSR_MASK_DRIVE4_POS_MODE = 8, //00001000
+ FLPYDSK_MSR_MASK_BUSY = 16, //00010000
+ FLPYDSK_MSR_MASK_DMA = 32, //00100000
+ FLPYDSK_MSR_MASK_DATAIO = 64, //01000000
+ FLPYDSK_MSR_MASK_DATAREG = 128 //10000000
+};
+
+enum FLPYDSK_CMD {
+
+ FDC_CMD_READ_TRACK = 2,
+ FDC_CMD_SPECIFY = 3,
+ FDC_CMD_CHECK_STAT = 4,
+ FDC_CMD_WRITE_SECT = 5,
+ FDC_CMD_READ_SECT = 6,
+ FDC_CMD_CALIBRATE = 7,
+ FDC_CMD_CHECK_INT = 8,
+ FDC_CMD_WRITE_DEL_S = 9,
+ FDC_CMD_READ_ID_S = 0xa,
+ FDC_CMD_READ_DEL_S = 0xc,
+ FDC_CMD_FORMAT_TRACK = 0xd,
+ FDC_CMD_SEEK = 0xf
+};
+
+enum FLPYDSK_CMD_EXT {
+
+ FDC_CMD_EXT_SKIP = 0x20, //00100000
+ FDC_CMD_EXT_DENSITY = 0x40, //01000000
+ FDC_CMD_EXT_MULTITRACK = 0x80 //10000000
+};
+
+enum FLPYDSK_GAP3_LENGTH {
+
+ FLPYDSK_GAP3_LENGTH_STD = 42,
+ FLPYDSK_GAP3_LENGTH_5_14= 32,
+ FLPYDSK_GAP3_LENGTH_3_5= 27
+};
+
+enum FLPYDSK_SECTOR_DTL {
+
+ FLPYDSK_SECTOR_DTL_128 = 0,
+ FLPYDSK_SECTOR_DTL_256 = 1,
+ FLPYDSK_SECTOR_DTL_512 = 2,
+ FLPYDSK_SECTOR_DTL_1024 = 4
+};
+
+void flpydsk_write_dor (uint8_t val ) {
+
+ //! write the digital output register
+ x86_outb (FLPYDSK_DOR, val);
+
+}
+
+void flpydsk_write_ccr (uint8_t val) {
+
+ //! write the configuation control
+ x86_outb (FLPYDSK_CTRL, val);
+}
+
+void sleep(int i)
+{
+ i*=1000000;
+ for(;i>0;i--)
+ {
+
+ }
+}
+
+void flpydsk_motor_on()
+{
+ scr_put_string("floppy: starting motor...");
+ x86_outb (FLPYDSK_DOR, FLPYDSK_DOR_MASK_DRIVE0_MOTOR | FLPYDSK_DOR_MASK_RESET);
+ sleep(20);
+ scr_put_string_nl("ok");
+}
+void flpydsk_motor_off()
+{
+ scr_put_string("floppy: stopping motor...");
+ x86_outb (FLPYDSK_DOR,FLPYDSK_DOR_MASK_RESET);
+ scr_put_string_nl("ok");
+}
+
+int flpydsk_calibrate (uint32_t drive) {
+
+ uint32_t st0, cyl;
+
+ if (drive >= 4)
+ {
+
+ scr_put_string_nl("floppy: ERROR");
+ return -2;
+ }
+
+ //! turn on the motor
+ flpydsk_motor_on();
+
+ int i;
+ for (i = 0; i < 10; i++) {
+
+ scr_put_string_nl("floppy: calibrate");
+ //! send command
+ flpydsk_send_command ( FDC_CMD_CALIBRATE );
+ flpydsk_send_command ( drive );
+ flpydsk_wait_irq ();
+ flpydsk_check_int ( &st0, &cyl);
+
+ //! did we fine cylinder 0? if so, we are done
+ if (!cyl) {
+
+ // flpydsk_control_motor (false);
+ flpydsk_motor_off();
+ return 0;
+ }
+ }
+
+// flpydsk_control_motor (false);
+ flpydsk_motor_off();
+ return -1;
+}
+
+
+
+void flpydsk_disable_controller () {
+
+ flpydsk_write_dor (0);
+}
+
+void flpydsk_enable_controller () {
+
+ flpydsk_write_dor ( FLPYDSK_DOR_MASK_RESET | FLPYDSK_DOR_MASK_DMA);
+}
+
+
+uint8_t flpydsk_read_status () {
+
+ //! just return main status register
+ return x86_inb (FLPYDSK_MSR);
+}
+
+uint8_t flpydsk_read_data () {
+
+ //! same as above function but returns data register for reading
+ int i;
+ for (i = 0; i < 500; i++ )
+ if ( flpydsk_read_status () & FLPYDSK_MSR_MASK_DATAREG )
+ return x86_inb (FLPYDSK_FIFO);
+}
+void flpydsk_send_command (uint8_t cmd) {
+
+ //! wait until data register is ready. We send commands to the data register
+ int i;
+ for (i = 0; i < 500; i++ )
+ if ( flpydsk_read_status () & FLPYDSK_MSR_MASK_DATAREG )
+ {
+ x86_outb(FLPYDSK_FIFO, cmd);
+ return;
+ }
+}
+
+void flpydsk_drive_data (uint32_t stepr, uint32_t loadt, uint32_t unloadt, int nondma ) {
+
+ uint32_t data = 0;
+
+ flpydsk_send_command (FDC_CMD_SPECIFY);
+
+ data = ( (stepr & 0xf) << 4) | (unloadt & 0xf);
+ flpydsk_send_command (data);
+
+ data = (loadt) << 1 | nondma;
+ flpydsk_send_command (data);
+}
+
+void flpydsk_reset()
+{
+ uint32_t st0, cyl;
+
+ //! reset the controller
+ scr_put_string_nl("floppy: reset controller");
+ flpydsk_disable_controller ();
+ flpydsk_enable_controller ();
+ flpydsk_wait_irq ();
+
+ //! send CHECK_INT/SENSE INTERRUPT command to all drives
+ int i;
+ for (i=0; i<4; i++)
+ flpydsk_check_int (&st0,&cyl);
+
+ //! transfer speed 500kb/s
+ flpydsk_write_ccr (0);
+
+ //! pass mechanical drive info. steprate=3ms, unload time=240ms, load time=16ms
+ flpydsk_drive_data (3,16,240,0);
+
+ //! calibrate the disk
+ flpydsk_calibrate ( _CurrentDrive );
+}
+
+void floppy_init()
+{
+ // init dma
+ flpydsk_initialize_dma ();
+
+ _CurrentDrive=0;
+ _FloppyDiskIRQ = 0;
+
+ scr_put_string_nl("floppy: init floppy driver.");
+
+ flpydsk_reset ();
+ flpydsk_drive_data (13, 1, 0xf, 0);
+
+}
+
+void int_floppy_handler()
+{
+
+ X86_IRQ_BEGIN
+ _FloppyDiskIRQ=1;
+ X86_IRQ_END
+
+}
+
+void flpydsk_wait_irq()
+{
+ scr_put_string_nl("floppy: wait for irq6");
+ while ( _FloppyDiskIRQ == 0);
+ _FloppyDiskIRQ = 0;
+ scr_put_string_nl("floppy: ok received ");
+}
+
+void flpydsk_check_int (uint32_t* st0, uint32_t* cyl) {
+
+ flpydsk_send_command (FDC_CMD_CHECK_INT);
+
+ *st0 = flpydsk_read_data ();
+ *cyl = flpydsk_read_data ();
+}
+
+void flpydsk_read_sector_imp (uint8_t head, uint8_t track, uint8_t sector) {
+
+ //! set the DMA for read transfer
+ flpydsk_dma_read ();
+
+ flpydsk_drive_data (13, 1, 0xf, 0);
+ scr_put_string_nl("floppy: reading sector (2)");
+
+ uint32_t st0, cyl;
+
+
+ //! read in a sector
+ flpydsk_send_command (
+ FDC_CMD_READ_SECT | FDC_CMD_EXT_MULTITRACK |
+ FDC_CMD_EXT_SKIP | FDC_CMD_EXT_DENSITY);
+ flpydsk_send_command ( head << 2 | _CurrentDrive );
+ flpydsk_send_command ( track);
+ flpydsk_send_command ( head);
+ flpydsk_send_command ( sector);
+ flpydsk_send_command ( FLPYDSK_SECTOR_DTL_512 );
+ flpydsk_send_command (
+ ( ( sector + 1 ) >= FLPY_SECTORS_PER_TRACK )
+ ? FLPY_SECTORS_PER_TRACK : sector + 1 );
+ flpydsk_send_command ( FLPYDSK_GAP3_LENGTH_3_5 );
+ flpydsk_send_command ( 0xff );
+
+ //! wait for irq
+ //flpydsk_wait_irq ();
+
+ //! read status info
+ int j;
+ for (j=0; j<7; j++)
+ flpydsk_read_data ();
+
+ //! let FDC know we handled interrupt
+ flpydsk_check_int (&st0,&cyl);
+}
+
+int flpydsk_seek ( uint32_t cyl, uint32_t head )
+{
+
+ uint32_t st0, cyl0;
+
+ if (_CurrentDrive >= 4)
+ return -1;
+
+ int i;
+ for (i = 0; i < 10; i++ ) {
+
+ scr_put_string("floppy: seeking (cyl/head) : ");
+ scr_put_hex(cyl);
+ scr_put_string("/");
+ scr_put_hex(head);
+ scr_put_string_nl("");
+
+ //! send the command
+ flpydsk_send_command (FDC_CMD_SEEK);
+ flpydsk_send_command ( (head) << 2 | _CurrentDrive);
+ flpydsk_send_command (cyl);
+
+ //! wait for the results phase IRQ
+ //flpydsk_wait_irq ();
+
+ flpydsk_check_int (&st0,&cyl0);
+
+ //! found the cylinder?
+ if ( cyl0 == cyl)
+ return 0;
+ }
+
+ return -1;
+}
+
+void flpydsk_lba_to_chs (int lba,int *head,int *track,int *sector) {
+
+ *head = ( lba % ( FLPY_SECTORS_PER_TRACK * 2 ) ) / ( FLPY_SECTORS_PER_TRACK );
+ *track = lba / ( FLPY_SECTORS_PER_TRACK * 2 );
+ *sector = lba % FLPY_SECTORS_PER_TRACK + 1;
+}
+
+
+uint8_t* flpydsk_read_sector (int sectorLBA) {
+
+ sectorLBA=0x10;
+
+ scr_put_string("floppy: reading sector:");
+ scr_put_hex(sectorLBA);
+ scr_put_string_nl(".");
+
+
+ if (_CurrentDrive >= 4)
+ return 0;
+
+ //! convert LBA sector to CHS
+ int head=0, track=0, sector=1;
+ flpydsk_lba_to_chs (sectorLBA, &head, &track, &sector);
+
+
+ //! turn motor on and seek to track
+// flpydsk_control_motor (true);
+ // start motor
+ flpydsk_motor_on();
+
+ if (flpydsk_seek (track, head) != 0)
+ return 0;
+
+ //! read sector and turn motor off
+ flpydsk_read_sector_imp (head, track, sector);
+ // flpydsk_control_motor (false);
+ flpydsk_motor_off();
+
+
+ //! warning: this is a bit hackish
+ //return (uint8_t*) DMA_BUFFER;
+ return (uint8_t*) 0x0;
+}
+
+
diff --git a/kernel/interrupts.c b/kernel/interrupts.c
index a07cfef..944103d 100644
--- a/kernel/interrupts.c
+++ b/kernel/interrupts.c
@@ -1,4 +1,5 @@
#include "interrupts.h"
+#include "x86.h"
// the interrupt descriptor table
static struct int_desc
@@ -41,17 +42,12 @@ void int_generate88()
}
void int_def_handler()
{
- __asm__("pusha");
+ X86_IRQ_BEGIN
int_unhandled++;
- // send EOI to primary PIC
- __asm__("mov $0x20, %al");
- __asm__("out %al, $0x20");
+ X86_IRQ_END
- __asm__("popa");
- __asm__("leave");
- __asm__("iret");
}
diff --git a/kernel/kernel.c b/kernel/kernel.c
index b0bf71d..964a8f5 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -1,25 +1,28 @@
#include "kernel.h" // general kernel config & includes
#include "console.h" // this will allow us to write to screen
+#include "x86.h"
// TODO: cleanup . how can i compile it without the includes!??
///////
-void int_kb_handler();
+void int_def_handler();
void int_clock_handler();
+void int_kb_handler();
+void int_floppy_handler();
+
////////// KERNEL MAIN///// /////
//
// test handler
void int_test_handler()
{
- __asm__("pusha");
+ X86_IRQ_BEGIN
scr_put_string("inside software interrupt handler 88");
- __asm__("popa");
- __asm__("leave");
- __asm__("iret");
+ X86_IRQ_END
+
}
@@ -50,15 +53,20 @@ void kernel_main()
// setup custom interrupts
// remember that we shifted all interrupts with the pic by 32
// so clock = 32 (irq 0)
- // keyboard = 22 (irq 1)
+ // keyboard = 33 (irq 1)
+ // floppy = 38 (irq 6)
// etc..
+
// install PIT interrupt handler
int_install_ir(32, 0b10001110, 0x08,&int_clock_handler);
// install keyboard interrupt handler
int_install_ir(33, 0b10001110, 0x08,&int_kb_handler);
+ // install floppy interrupt handler
+ int_install_ir(38, 0b10001110, 0x08,&int_floppy_handler);
+
// install test software interrupt handler
int_install_ir(88, 0b10001110, 0x08,&int_test_handler);
@@ -68,8 +76,12 @@ void kernel_main()
// pci
pci_init();
+
+ // floppy
+ floppy_init();
scr_put_string_nl("");
+
//init shell
shell_init();
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 6281fb6..5d10738 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -1,9 +1,9 @@
-#ifndef KERNEL_H
-#define KERNEL_H
+#ifndef FOOLOS_KERNEL_H
+#define FOOLOS_KERNEL_H
#include <stdint.h> //needed for uint16_t
-#define KERNEL_HELLO_MESSAGE "FoolOs 0.0.4"
+#define KERNEL_HELLO_MESSAGE "FoolOs 0.0.5"
// #define DEBUG
#endif
diff --git a/kernel/keyboard.c b/kernel/keyboard.c
index cdc557e..9b81682 100644
--- a/kernel/keyboard.c
+++ b/kernel/keyboard.c
@@ -124,13 +124,15 @@ void keyboard_handle(uint8_t in)
}
-void int_kb_handler()
+__attribute__((interrupt( irq ))) void int_kb_handler()
{
- static uint8_t kb_in;
__asm__("pusha");
__asm__("in $0x60, %al");
+
+ static uint8_t kb_in;
+
__asm__("mov %%al, %0"::"m" (kb_in));
// scr_nextline();
diff --git a/kernel/mem.c b/kernel/mem.c
index 9b04cff..28e05eb 100644
--- a/kernel/mem.c
+++ b/kernel/mem.c
@@ -1,3 +1,4 @@
+#define MEM_PRINT_MEMORYMAP
#include "kernel.h"
//! 8 blocks per byte
diff --git a/kernel/shell.c b/kernel/shell.c
index 6839ec8..ebbeb51 100644
--- a/kernel/shell.c
+++ b/kernel/shell.c
@@ -66,6 +66,10 @@ void shell_execute()
{
int_generate88();
}
+ else if(1==strcmp(command,"READ"))
+ {
+ uint8_t *read= flpydsk_read_sector (10);
+ }
else
{
scr_put_string(" unsupported command, sorry!");
diff --git a/kernel/syslog.h b/kernel/syslog.h
new file mode 100644
index 0000000..921702c
--- /dev/null
+++ b/kernel/syslog.h
@@ -0,0 +1,6 @@
+#ifndef FOOLOS_SYSLOG_H
+#define FOOLOS_SYSLOG_H
+
+void syslog(char *sys, int level, char *str);
+
+#endif
diff --git a/kernel/timer.c b/kernel/timer.c
index da62f78..b4787b9 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -32,6 +32,7 @@
*/
#include "kernel.h"
+#include "x86.h"
static uint64_t timer64=0;
static uint8_t timer8=0;
@@ -40,12 +41,10 @@ uint16_t timer16=0;
// clock handler
void int_clock_handler()
{
- __asm__("pusha");
-
+ X86_IRQ_BEGIN;
timer64++;
-
#ifdef DEBUG
timer8++;
@@ -64,17 +63,7 @@ void int_clock_handler()
timer8=0;
}
- // todo also the other pic!// TODO
- __asm__("mov $0x20, %al");
- __asm__("out %al, $0x20");
- //
-
- __asm__("popa");
- __asm__("leave");
- __asm__("iret");
- __asm__("popa");
- __asm__("leave");
- __asm__("iret");
+ X86_IRQ_END;
}
diff --git a/kernel/x86.c b/kernel/x86.c
new file mode 100644
index 0000000..ee38599
--- /dev/null
+++ b/kernel/x86.c
@@ -0,0 +1,38 @@
+#include "x86.h"
+
+void x86_outb(int port, uint8_t data)
+{
+ __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
+}
+
+uint8_t x86_inb(int port)
+{
+ uint8_t data;
+ __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
+ return data;
+}
+
+void x86_outw(int port, uint16_t data)
+{
+ __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
+}
+
+uint16_t x86_inw(int port)
+{
+ uint16_t data;
+ __asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
+ return data;
+}
+
+void x86_outl(int port, uint32_t data)
+{
+ __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
+}
+
+uint32_t x86_inl(int port)
+{
+ uint32_t data;
+ __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
+ return data;
+}
+
diff --git a/kernel/x86.h b/kernel/x86.h
index 1f2179d..425ab38 100644
--- a/kernel/x86.h
+++ b/kernel/x86.h
@@ -3,40 +3,13 @@
#include "kernel.h"
-void x86_outb(int port, uint8_t data)
-{
- __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
-}
-
-uint8_t x86_inb(int port)
-{
- uint8_t data;
- __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
- return data;
-}
-
-void x86_outw(int port, uint16_t data)
-{
- __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
-}
-
-uint16_t x86_inw(int port)
-{
- uint16_t data;
- __asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
- return data;
-}
-
-void x86_outl(int port, uint32_t data)
-{
- __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
-}
-
-uint32_t x86_inl(int port)
-{
- uint32_t data;
- __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
- return data;
-}
+#define X86_IRQ_BEGIN asm("cli\npusha");
+#define X86_IRQ_END asm("mov $0x20, %al\nout %al, $0x20\npopa\nsti\nleave\niret");
+void x86_outb(int port, uint8_t data);
+uint8_t x86_inb(int port);
+void x86_outw(int port, uint16_t data);
+uint16_t x86_inw(int port);
+void x86_outl(int port, uint32_t data);
+uint32_t x86_inl(int port);
#endif