277 lines
5.1 KiB
C
277 lines
5.1 KiB
C
//Functions.c
|
|
//05/07/03 Josh Holtrop
|
|
//for HOS
|
|
//Modified: 10/30/03
|
|
|
|
//Writes a byte out to a port
|
|
inline void outportb(unsigned int port, unsigned char value) // Output a byte to a port
|
|
{
|
|
asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
|
|
};
|
|
|
|
//Writes a word out to a port
|
|
inline void outportw(unsigned int port, unsigned int value) // Output a word to a port
|
|
{
|
|
asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value));
|
|
};
|
|
|
|
//Reads a byte from a port
|
|
inline byte inportb(unsigned short port)
|
|
{
|
|
unsigned char ret_val;
|
|
|
|
asm volatile("inb %w1,%b0"
|
|
: "=a"(ret_val)
|
|
: "d"(port));
|
|
return ret_val;
|
|
};
|
|
|
|
//Enables (SeTs) Interrupt Flag on the processor
|
|
inline void enable_ints()
|
|
{
|
|
asm("sti");
|
|
};
|
|
|
|
//Disables (CLears) Interrupt Flag on the processor
|
|
inline void disable_ints()
|
|
{
|
|
asm("cli");
|
|
};
|
|
|
|
|
|
char *strcat(char *dest, char *src)
|
|
{
|
|
strcpy(dest+strlen(dest), src);
|
|
}
|
|
|
|
|
|
//converts a binary-coded-decimal byte to its decimal equivalent
|
|
inline byte bcd2byte(byte bcd)
|
|
{
|
|
return (10* ((bcd & 0xF0) >> 4)) + (bcd & 0x0F);
|
|
}
|
|
|
|
//converts a binary-coded-decimal byte to its decimal equivalent
|
|
inline byte byte2bcd(byte bite)
|
|
{
|
|
return ((bite / 10) << 4) | (bite % 10);
|
|
}
|
|
|
|
void rtrim(char *str)
|
|
{
|
|
str += strlen(str); //now points to the null character at the end of the string
|
|
str--;
|
|
for (;;)
|
|
{
|
|
if ((*str == ' ') || (*str == '\t') || (*str == '\n'))
|
|
*str-- = 0;
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
char *ucase(char *str)
|
|
{
|
|
char *ret = str;
|
|
for (;;)
|
|
{
|
|
if (*str == 0)
|
|
break;
|
|
if ((*str >= 'a') && (*str <= 'z'))
|
|
*str = (*str) - 32;
|
|
str++;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
char *lcase(char *str)
|
|
{
|
|
char *ret = str;
|
|
for (;;)
|
|
{
|
|
if (*str == 0)
|
|
break;
|
|
if ((*str >= 'A') && (*str <= 'Z'))
|
|
*str = (*str) + 32;
|
|
str++;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
//Re-maps the Programmable Interrupr Controllers so IRQ0->pic1 base address, IRG8->pic2 base address
|
|
void remap_pics(int pic1, int pic2)
|
|
{
|
|
byte a1, a2;
|
|
|
|
a1 = inportb(PIC1_DATA); //0x21
|
|
a2 = inportb(PIC2_DATA); //0xA1
|
|
|
|
outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); //0x20, 0x10+0x01 00010001b
|
|
outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); //0xA0, 0x10+0x01 00010001b
|
|
outportb(PIC1_DATA, pic1); //0x21, pic1
|
|
outportb(PIC2_DATA, pic2); //0xA1, pic2
|
|
outportb(PIC1_DATA, 4); //0x21, 0x04 00000100b
|
|
outportb(PIC2_DATA, 2); //0xA1, 0x02 00000010b
|
|
outportb(PIC1_DATA, ICW4_8086); //0x21, 0x01 00000001b
|
|
outportb(PIC2_DATA, ICW4_8086); //0xA1, 0x01 00000001b
|
|
|
|
outportb(PIC1_DATA, a1); //0x21
|
|
outportb(PIC2_DATA, a2); //0xA1
|
|
}
|
|
|
|
//Masks interrupts on first Programmable Interrupt Controller
|
|
inline void pic1_mask(byte mask)
|
|
{
|
|
outportb(PIC1_DATA, mask); //0x21, maskfield *OCW1*
|
|
}
|
|
|
|
//Masks interrupts on second Programmable Interrupt Controller
|
|
inline void pic2_mask(byte mask)
|
|
{
|
|
outportb(PIC2_DATA, mask); //0xA1, maskfield *OCW1*
|
|
}
|
|
|
|
//Restarts the computer
|
|
inline void restart()
|
|
{
|
|
enable_ints();
|
|
byte temp;
|
|
do
|
|
{
|
|
temp = inportb(0x64);
|
|
if (temp & 1)
|
|
inportb(0x60);
|
|
} while(temp & 2);
|
|
|
|
|
|
outportb (0x64, 0xfe);
|
|
for (;;)
|
|
{
|
|
}
|
|
}
|
|
|
|
//Halts (freezes) the computer
|
|
inline void halt()
|
|
{
|
|
asm("cli");
|
|
asm("hlt");
|
|
while (1)
|
|
;
|
|
}
|
|
|
|
//Initializes 8253 Programmable Interrupt Timer
|
|
inline void init_timer()
|
|
{
|
|
//set timer : 2e9c = 100hz
|
|
outportb(0x43, 0x34);
|
|
outportb(0x40, 0x9c); //lsb
|
|
outportb(0x40, 0x2e); //msb
|
|
}
|
|
|
|
//Signals an End Of Interrupt signal to the first PIC
|
|
inline void eoi()
|
|
{
|
|
outportb(0x20, 0x20);
|
|
}
|
|
|
|
//Signals an End Of Interrupt signal to both the second and first PIC unit
|
|
inline void eoi2()
|
|
{
|
|
outportb(0xA0, 0x20);
|
|
outportb(0x20, 0x20);
|
|
}
|
|
|
|
//Returns the size of the kernel (code & data)
|
|
// - this does not include the bss section
|
|
// - this should be 4kb aligned per the linker script
|
|
// - this should be the size of kernel.bin
|
|
inline dword kernel_size()
|
|
{
|
|
return (dword)(&_bss)-(dword)(&_code);
|
|
}
|
|
|
|
|
|
//These functions are for reading and writing various values stored on the CMOS Real Time Clock
|
|
byte rtc_readDay()
|
|
{
|
|
outportb(0x70, 7);
|
|
return bcd2byte(inportb(0x71));
|
|
}
|
|
|
|
byte rtc_readMonth()
|
|
{
|
|
outportb(0x70, 8);
|
|
return bcd2byte(inportb(0x71));
|
|
}
|
|
|
|
byte rtc_readYear()
|
|
{
|
|
outportb(0x70, 9);
|
|
return bcd2byte(inportb(0x71));
|
|
}
|
|
|
|
byte rtc_readSecond()
|
|
{
|
|
outportb(0x70, 0);
|
|
return bcd2byte(inportb(0x71));
|
|
}
|
|
|
|
byte rtc_readMinute()
|
|
{
|
|
outportb(0x70, 2);
|
|
return bcd2byte(inportb(0x71));
|
|
}
|
|
|
|
byte rtc_readHour()
|
|
{
|
|
outportb(0x70, 4);
|
|
return bcd2byte(inportb(0x71));
|
|
}
|
|
|
|
void rtc_setDay(byte day)
|
|
{
|
|
outportb(0x70, 7);
|
|
outportb(0x71, byte2bcd(day));
|
|
}
|
|
|
|
void rtc_setMonth(byte month)
|
|
{
|
|
outportb(0x70, 8);
|
|
outportb(0x71, byte2bcd(month));
|
|
}
|
|
|
|
void rtc_setYear(byte year)
|
|
{
|
|
outportb(0x70, 9);
|
|
outportb(0x71, byte2bcd(year));
|
|
}
|
|
|
|
void rtc_setSecond(byte second)
|
|
{
|
|
outportb(0x70, 0);
|
|
outportb(0x71, byte2bcd(second));
|
|
}
|
|
|
|
void rtc_setMinute(byte minute)
|
|
{
|
|
outportb(0x70, 2);
|
|
outportb(0x71, byte2bcd(minute));
|
|
}
|
|
|
|
void rtc_setHour(byte hour)
|
|
{
|
|
outportb(0x70, 4);
|
|
outportb(0x71, byte2bcd(hour));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|