CTAOS v2
This commit is contained in:
		
							
								
								
									
										104
									
								
								include/system.h
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								include/system.h
									
									
									
									
									
								
							@@ -1,104 +0,0 @@
 | 
			
		||||
#ifndef __SYSTEM_H
 | 
			
		||||
#define __SYSTEM_H
 | 
			
		||||
 | 
			
		||||
// Data type declarations
 | 
			
		||||
typedef unsigned char byte;
 | 
			
		||||
typedef unsigned short word;
 | 
			
		||||
typedef unsigned int dword;
 | 
			
		||||
 | 
			
		||||
/* This defines what the stack looks like after an ISR was running */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    unsigned int gs, fs, es, ds;      /* pushed the segs last */
 | 
			
		||||
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;  /* pushed by 'pusha' */
 | 
			
		||||
    unsigned int int_no, err_code;    /* our 'push byte #' and ecodes do this */
 | 
			
		||||
    unsigned int eip, cs, eflags, useresp, ss;   /* pushed by the processor automatically */ 
 | 
			
		||||
} regs;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte *TextVideoRam;
 | 
			
		||||
int cursor_x, cursor_y;
 | 
			
		||||
int current_mode_width;
 | 
			
		||||
int current_mode_height;
 | 
			
		||||
 | 
			
		||||
// System functions declaration
 | 
			
		||||
void system_init();
 | 
			
		||||
void *memcpy(void *dest, const void *src, int count);
 | 
			
		||||
void *memset(void *dest, char val, int count);
 | 
			
		||||
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count);
 | 
			
		||||
int strlen (const char *str);
 | 
			
		||||
byte inportb (word _port);
 | 
			
		||||
byte inb (word _port);
 | 
			
		||||
void outportb (word _port, byte _data);
 | 
			
		||||
void outb (word _port, byte _data) ;
 | 
			
		||||
 | 
			
		||||
// GDT, IDT, ISRs, IRQ functions declarations
 | 
			
		||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
 | 
			
		||||
void gdt_install();
 | 
			
		||||
 | 
			
		||||
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
 | 
			
		||||
void idt_install();
 | 
			
		||||
 | 
			
		||||
void isrs_install();
 | 
			
		||||
 | 
			
		||||
void irq_install_handler(int irq, void (*handler)(regs *r));
 | 
			
		||||
void irq_uninstall_handler(int irq);
 | 
			
		||||
void irq_install();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Initialize system
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void *memcpy(void *dest, const void *src, int count)
 | 
			
		||||
{
 | 
			
		||||
    const char *sp = (const char *)src;
 | 
			
		||||
    char *dp = (char *)dest;
 | 
			
		||||
    for(; count != 0; count--) *dp++ = *sp++;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *memset(void *dest, char val, int count)
 | 
			
		||||
{
 | 
			
		||||
    char *temp = (char *)dest;
 | 
			
		||||
    for( ; count != 0; count--) *temp++ = val;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
 | 
			
		||||
{
 | 
			
		||||
    unsigned short *temp = (unsigned short *)dest;
 | 
			
		||||
    for( ; count != 0; count--) *temp++ = val;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// strlen -- Get lenght of str
 | 
			
		||||
int strlen (const char *str)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; str[i]!=0; i++) {}
 | 
			
		||||
      return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte inportb (word _port) {
 | 
			
		||||
      byte rv;
 | 
			
		||||
      __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
 | 
			
		||||
      return rv;
 | 
			
		||||
}
 | 
			
		||||
byte inb (word _port) {
 | 
			
		||||
      byte rv;
 | 
			
		||||
      __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
 | 
			
		||||
      return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void outportb (word _port, byte _data) {
 | 
			
		||||
      __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
 | 
			
		||||
}
 | 
			
		||||
void outb (word _port, byte _data) {
 | 
			
		||||
      __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										37
									
								
								init.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								init.c
									
									
									
									
									
								
							@@ -1,37 +0,0 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void system_init()
 | 
			
		||||
{
 | 
			
		||||
      // Detect if color/monochrome screen
 | 
			
		||||
	char c = (*(volatile unsigned short*)0x410)&0x30;
 | 
			
		||||
	if (c==0x30) TextVideoRam = (byte *)0xb0000;
 | 
			
		||||
	else TextVideoRam = (byte *)0xb8000;
 | 
			
		||||
	
 | 
			
		||||
	// Reset cursor, use 80x25 text video mode
 | 
			
		||||
	current_mode_width = 80;
 | 
			
		||||
	current_mode_height = 25;
 | 
			
		||||
	cursor_x = cursor_y = 0;
 | 
			
		||||
	
 | 
			
		||||
	// Install GDT, IDT, ISRs and IRQs; Enable interrupts
 | 
			
		||||
      gdt_install();
 | 
			
		||||
      idt_install();
 | 
			
		||||
	isrs_install();
 | 
			
		||||
	irq_install();
 | 
			
		||||
      __asm__ __volatile__ ("sti");
 | 
			
		||||
	 
 | 
			
		||||
      // Install PIT timer
 | 
			
		||||
      timer_ticks = 0;
 | 
			
		||||
      irq_install_handler(0, timer_handler);
 | 
			
		||||
      timer_phase (100);
 | 
			
		||||
      
 | 
			
		||||
      // Install keyboard
 | 
			
		||||
      kb_modifier_status = 0;
 | 
			
		||||
      kb_lights_status = 0xFF; kb_update_LED();
 | 
			
		||||
      kb_lights_status = 0; kb_update_LED();
 | 
			
		||||
      irq_install_handler(1, kb_handler);
 | 
			
		||||
      
 | 
			
		||||
      // mouse_driver();
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								kernel.bin
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								kernel.bin
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										25
									
								
								kernel/clock/cmos.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								kernel/clock/cmos.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
volatile static byte cmos_data[128];
 | 
			
		||||
 | 
			
		||||
void cmos_write ()
 | 
			
		||||
{
 | 
			
		||||
      byte i;
 | 
			
		||||
      for (i = 0; i < 128; i++) {
 | 
			
		||||
            //asm volatile ("cli");
 | 
			
		||||
            outportb(0x70, i);
 | 
			
		||||
            iowait();
 | 
			
		||||
            outportb(0x71, cmos_data[i]);
 | 
			
		||||
            //asm volatile ("sti");
 | 
			
		||||
            }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cmos_read ()
 | 
			
		||||
{
 | 
			
		||||
      byte i;
 | 
			
		||||
      for (i = 0; i < 128; i++) {
 | 
			
		||||
            //asm volatile ("cli");
 | 
			
		||||
            outportb(0x70, i);
 | 
			
		||||
            iowait();
 | 
			
		||||
            cmos_data[i] = inportb(0x71);
 | 
			
		||||
            //asm volatile ("sti");
 | 
			
		||||
            }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								kernel/clock/pictimer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								kernel/clock/pictimer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
#include "time.c"
 | 
			
		||||
int timer_ticks = 0;
 | 
			
		||||
int timer_hz;
 | 
			
		||||
 | 
			
		||||
void timer_phase(int hz)
 | 
			
		||||
{
 | 
			
		||||
      int divisor = 1193180/hz;           // 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
 | 
			
		||||
      timer_hz = hz;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clock_show (int uptime_secs)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i=0;i<80;i++) putc_pos_font (i, 0, ' ', 0x02, 0x0F);
 | 
			
		||||
      puts_pos_font (64, 0, "Uptime:", 0x02, 0x0E);
 | 
			
		||||
 | 
			
		||||
      unsigned int uptime;
 | 
			
		||||
 | 
			
		||||
      uptime = uptime_secs%60;                // Seconds
 | 
			
		||||
      uptime += 100* ((uptime_secs/60)%60);   // Minutes
 | 
			
		||||
      uptime += 10000*(uptime_secs/3600);     // Hours
 | 
			
		||||
      
 | 
			
		||||
      for (i=79;i>71;i--) {
 | 
			
		||||
            if (i==77 || i==74) {
 | 
			
		||||
                  if (uptime_secs%2==0) putc_pos_font(i, 0, ':', 0x02, 0x0F);
 | 
			
		||||
                  else putc_pos_font(i, 0, ' ', 0x02, 0x0F);
 | 
			
		||||
                  }
 | 
			
		||||
            else {
 | 
			
		||||
                  putc_pos_font(i, 0, (uptime%10)+'0', 0x02, 0x0F);
 | 
			
		||||
                  uptime/=10;
 | 
			
		||||
                  }
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // PRINT CURRENT TIME
 | 
			
		||||
      uptime = clock.seconds;          // Seconds
 | 
			
		||||
      uptime += 100* clock.minutes;   // Minutes
 | 
			
		||||
      uptime += 10000*clock.hours;     // Hours
 | 
			
		||||
      
 | 
			
		||||
      for (i=9;i>1;i--) {
 | 
			
		||||
            if (i==7 || i==4) {
 | 
			
		||||
                  if (uptime_secs%2==0) putc_pos_font(i, 0, ':', 0x02, 0x0F);
 | 
			
		||||
                  else putc_pos_font(i, 0, ' ', 0x02, 0x0F);
 | 
			
		||||
                  }
 | 
			
		||||
            else {
 | 
			
		||||
                  putc_pos_font(i,0, (uptime%10)+'0', 0x02, 0x0F);
 | 
			
		||||
                  uptime/=10;
 | 
			
		||||
                  }
 | 
			
		||||
      }
 | 
			
		||||
      if (clock.am_pm==0) puts_pos_font(10, 0, "am", 0x02, 0x0F);
 | 
			
		||||
      else puts_pos_font(10, 0, "pm", 0x02, 0x0F);
 | 
			
		||||
      
 | 
			
		||||
      // PRINT DATE
 | 
			
		||||
      putc_pos_font(32, 0, (clock.day/10)+'0', 0x02, 0x0E);
 | 
			
		||||
      putc_pos_font(33, 0, (clock.day%10)+'0', 0x02, 0x0E);
 | 
			
		||||
      puts_pos_font(35, 0, (char*)clock_months[clock.month], 0x02, 0x0F);
 | 
			
		||||
      putc_pos_font(35+strlen(clock_months[clock.month])+1, 0, (clock.century/10)+'0', 0x02, 0x0E);
 | 
			
		||||
      putc_pos_font(35+strlen(clock_months[clock.month])+2, 0, (clock.century%10)+'0', 0x02, 0x0E);
 | 
			
		||||
      putc_pos_font(35+strlen(clock_months[clock.month])+3, 0, (clock.year/10)+'0', 0x02, 0x0E);
 | 
			
		||||
      putc_pos_font(35+strlen(clock_months[clock.month])+4, 0, (clock.year%10)+'0', 0x02, 0x0E);
 | 
			
		||||
      
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void timer_handler(regs *r)
 | 
			
		||||
{
 | 
			
		||||
      timer_ticks++;
 | 
			
		||||
      
 | 
			
		||||
      if (timer_ticks % timer_hz == 0) {
 | 
			
		||||
            clock_show (timer_ticks / timer_hz);
 | 
			
		||||
            clock_inc();
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										143
									
								
								kernel/clock/time.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								kernel/clock/time.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
#ifndef __TIME_C
 | 
			
		||||
#define __TIME_C
 | 
			
		||||
 | 
			
		||||
#include "cmos.h"
 | 
			
		||||
 | 
			
		||||
static const char* clock_months[] = {0, 
 | 
			
		||||
      "January", "February", "March", "April", "May", "June",
 | 
			
		||||
      "July", "August", "September", "October", "November", "December"};
 | 
			
		||||
static const char* clock_weekdays[] = {0,
 | 
			
		||||
      "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
 | 
			
		||||
 | 
			
		||||
byte clock_months_len[] = {
 | 
			
		||||
      0,
 | 
			
		||||
      31,   // January
 | 
			
		||||
      28,   // February
 | 
			
		||||
      31,   // March
 | 
			
		||||
      30,   // April
 | 
			
		||||
      31,   // May
 | 
			
		||||
      30,   // June
 | 
			
		||||
      31,   // July
 | 
			
		||||
      31,   // August
 | 
			
		||||
      30,   // September
 | 
			
		||||
      31,   // October
 | 
			
		||||
      30,   // November
 | 
			
		||||
      31    // December
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
      byte seconds;
 | 
			
		||||
      byte minutes;
 | 
			
		||||
      byte hours;
 | 
			
		||||
      byte weekday;
 | 
			
		||||
      byte day;
 | 
			
		||||
      byte month;
 | 
			
		||||
      byte year;
 | 
			
		||||
      byte century;
 | 
			
		||||
      byte am_pm;
 | 
			
		||||
      
 | 
			
		||||
} TIME;
 | 
			
		||||
volatile static TIME clock;
 | 
			
		||||
 | 
			
		||||
void RTC_get_time()
 | 
			
		||||
{
 | 
			
		||||
      cmos_read();
 | 
			
		||||
      
 | 
			
		||||
      if ((cmos_data[0x0b]&4)==0) // BCD = true;
 | 
			
		||||
      {
 | 
			
		||||
            clock.seconds = (cmos_data[0x00]%16) + 10*(cmos_data[0x00]/16);
 | 
			
		||||
            clock.minutes = (cmos_data[0x02]%16) + 10*(cmos_data[0x02]/16);
 | 
			
		||||
            if ((cmos_data[0x0b]&2)==0) { // AM/PM
 | 
			
		||||
                        if (cmos_data[0x04]&80) { // pm
 | 
			
		||||
                          clock.hours = ((cmos_data[0x04]-0x80)%16) + 10*((cmos_data[0x04]-0x80)/16);
 | 
			
		||||
                          clock.am_pm = 1;
 | 
			
		||||
                        }
 | 
			
		||||
                        else { // am
 | 
			
		||||
                          clock.hours = (cmos_data[0x04]%16) + 10*(cmos_data[0x04]/16);
 | 
			
		||||
                          clock.am_pm = 0;
 | 
			
		||||
                        }
 | 
			
		||||
            }
 | 
			
		||||
            else { // 24 hours
 | 
			
		||||
                          clock.hours = (cmos_data[0x04]%16) + 10*(cmos_data[0x04]/16);
 | 
			
		||||
                          if (clock.hours > 12) {
 | 
			
		||||
                              clock.am_pm = 1;
 | 
			
		||||
                              clock.hours -= 12;
 | 
			
		||||
                          }
 | 
			
		||||
                          else clock.am_pm = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            clock.weekday = (cmos_data[0x06]%16) + 10*(cmos_data[0x06]/16);
 | 
			
		||||
            clock.day = (cmos_data[0x07]%16) + 10*(cmos_data[0x07]/16);
 | 
			
		||||
            clock.month = (cmos_data[0x08]%16) + 10*(cmos_data[0x08]/16);
 | 
			
		||||
            clock.year = (cmos_data[0x09]%16) + 10*(cmos_data[0x09]/16);
 | 
			
		||||
            clock.century = (cmos_data[0x32]%16) + 10*(cmos_data[0x32]/16);
 | 
			
		||||
      }
 | 
			
		||||
            
 | 
			
		||||
      else {//BCD = false;
 | 
			
		||||
            clock.seconds = cmos_data[0x00];
 | 
			
		||||
            clock.minutes = cmos_data[0x02];
 | 
			
		||||
            if ((cmos_data[0x0b]&2)==0) { // AM/PM
 | 
			
		||||
                        if (cmos_data[0x04]&80) { // pm
 | 
			
		||||
                          clock.hours = cmos_data[0x04]-0x80;
 | 
			
		||||
                          clock.am_pm = 1;
 | 
			
		||||
                        }
 | 
			
		||||
                        else { // am
 | 
			
		||||
                          clock.hours = cmos_data[0x04];
 | 
			
		||||
                          clock.am_pm = 0;
 | 
			
		||||
                        }
 | 
			
		||||
            }
 | 
			
		||||
            else { // 24 hours
 | 
			
		||||
                          clock.hours = cmos_data[0x02];
 | 
			
		||||
                          if (clock.hours > 12) {
 | 
			
		||||
                              clock.am_pm = 1;
 | 
			
		||||
                              clock.hours -= 12;
 | 
			
		||||
                          }
 | 
			
		||||
                          else clock.am_pm = 0;
 | 
			
		||||
            }
 | 
			
		||||
            clock.weekday = cmos_data[0x06];
 | 
			
		||||
            clock.day = cmos_data[0x07];
 | 
			
		||||
            clock.month = cmos_data[0x08];
 | 
			
		||||
            clock.year = cmos_data[0x09];
 | 
			
		||||
            clock.century = cmos_data[0x32];
 | 
			
		||||
      }
 | 
			
		||||
      // Leap years
 | 
			
		||||
      if (clock.year % 4 == 0) clock_months_len[2]=29;
 | 
			
		||||
      
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clock_inc()
 | 
			
		||||
{
 | 
			
		||||
      // New minute
 | 
			
		||||
      if (++clock.seconds > 59) {
 | 
			
		||||
            clock.seconds = 0;
 | 
			
		||||
            // New hour
 | 
			
		||||
            if (++clock.minutes > 59) {
 | 
			
		||||
                  clock.minutes = 0;
 | 
			
		||||
                  clock.hours++;
 | 
			
		||||
		  if (clock.hours == 12 && clock.am_pm == 1) {     // 11:59pm -> 0:00am
 | 
			
		||||
                        clock.hours = 0; clock.am_pm = 0;
 | 
			
		||||
                        // New day
 | 
			
		||||
                        clock.weekday = 1+(clock.weekday%7);
 | 
			
		||||
                        // New month
 | 
			
		||||
			if (++clock.day > clock_months_len[clock.month]) {
 | 
			
		||||
			      clock.day = 1;
 | 
			
		||||
			      // New year
 | 
			
		||||
			      if (++clock.month>12) {
 | 
			
		||||
				    clock.month = 1;
 | 
			
		||||
				    // New century
 | 
			
		||||
				    if (++clock.year > 99) {
 | 
			
		||||
					  clock.year = 0;
 | 
			
		||||
					  clock.century++;
 | 
			
		||||
				    }
 | 
			
		||||
			      }
 | 
			
		||||
			}
 | 
			
		||||
		  }
 | 
			
		||||
		  else if (clock.hours == 12 && clock.am_pm == 0) // 11:59am -> 12:00pm
 | 
			
		||||
			clock.am_pm = 1;
 | 
			
		||||
		  else if (clock.hours == 13 && clock.am_pm == 1) // 12:59pm -> 1:59pm
 | 
			
		||||
			clock.hours = 1;
 | 
			
		||||
	    }
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -10,7 +10,7 @@ set djgpp_path=C:\DJGPP\bin
 | 
			
		||||
rem Compile loader
 | 
			
		||||
%nasm_path%\nasm.exe -f aout -o %loader_name%.o %loader_name%.asm
 | 
			
		||||
rem Compile main Kernel
 | 
			
		||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c
 | 
			
		||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c 
 | 
			
		||||
rem OTHER GCC/NASM SOURCES GO HERE
 | 
			
		||||
 | 
			
		||||
@echo on
 | 
			
		||||
@@ -19,4 +19,5 @@ rem OTHER GCC/NASM SOURCES GO HERE
 | 
			
		||||
@echo Done!
 | 
			
		||||
 | 
			
		||||
@pause
 | 
			
		||||
copy C:\CTAOS\KERNEL.BIN C:\SHARE
 | 
			
		||||
copy KERNEL.BIN C:\SHARE
 | 
			
		||||
copy KERNEL.BIN A:\KERNEL.CTA
 | 
			
		||||
@@ -1,11 +1,13 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
 | 
			
		||||
#ifndef __CONSOLE_H
 | 
			
		||||
#define __CONSOLE_H
 | 
			
		||||
#ifndef __CONIO_H
 | 
			
		||||
#define __CONIO_H
 | 
			
		||||
#define _ATTRIB 0x0F
 | 
			
		||||
 | 
			
		||||
byte default_background, default_foreground;
 | 
			
		||||
 | 
			
		||||
char hex[] = "0123456789ABCDEF";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Change cursor position
 | 
			
		||||
void text_mode_cursor(int x, int y)
 | 
			
		||||
@@ -55,7 +57,15 @@ void scroll(int n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void _endl()
 | 
			
		||||
void prev_line()
 | 
			
		||||
{
 | 
			
		||||
      cursor_x = 79;
 | 
			
		||||
      if (--cursor_y < 0) {
 | 
			
		||||
            cursor_y = 0; cursor_x=0;
 | 
			
		||||
            }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void next_line()
 | 
			
		||||
{
 | 
			
		||||
      cursor_x = 0;
 | 
			
		||||
      if (++cursor_y >=25) {
 | 
			
		||||
@@ -78,9 +88,9 @@ void putc_pos(int x, int y, char c)
 | 
			
		||||
// Put character on screen in the current cursor position; different font colors
 | 
			
		||||
void putc_font(char c, byte back, byte fore)
 | 
			
		||||
{
 | 
			
		||||
      if (cursor_x > current_mode_width) _endl();
 | 
			
		||||
      if (cursor_x >= current_mode_width) next_line();
 | 
			
		||||
      
 | 
			
		||||
      if (c == '\n') {_endl(); return;};
 | 
			
		||||
      if (c == '\n') {next_line(); return;};
 | 
			
		||||
      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c;
 | 
			
		||||
      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)+1] = fore|(back<<4);
 | 
			
		||||
      cursor_x++;
 | 
			
		||||
@@ -88,9 +98,9 @@ void putc_font(char c, byte back, byte fore)
 | 
			
		||||
// Put character on screen in the current cursor position; default font colors
 | 
			
		||||
void putc(char c)
 | 
			
		||||
{
 | 
			
		||||
      if (cursor_x > current_mode_width) _endl();
 | 
			
		||||
      if (cursor_x >= current_mode_width) next_line();
 | 
			
		||||
 | 
			
		||||
      if (c == '\n') {_endl(); return;};
 | 
			
		||||
      if (c == '\n') {next_line(); return;};
 | 
			
		||||
      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c;
 | 
			
		||||
      cursor_x++;
 | 
			
		||||
}
 | 
			
		||||
@@ -125,9 +135,8 @@ void puts_font(char *str, byte back, byte fore)
 | 
			
		||||
            putc_font(str[i], back, fore);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void put_hex(int x, int y, unsigned int alpha)
 | 
			
		||||
void put_hex(unsigned int alpha)
 | 
			
		||||
{
 | 
			
		||||
      char hex[] = "0123456789ABCDEF";
 | 
			
		||||
      char nr[9];
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 7; i >= 0; i--) {
 | 
			
		||||
@@ -135,7 +144,18 @@ void put_hex(int x, int y, unsigned int alpha)
 | 
			
		||||
            alpha /= 16;
 | 
			
		||||
            }
 | 
			
		||||
      nr[8] = 0;
 | 
			
		||||
      puts_pos(x, y, nr);
 | 
			
		||||
      puts(nr);
 | 
			
		||||
}
 | 
			
		||||
void put_hex_pos(int x, int y, unsigned int alpha)
 | 
			
		||||
{
 | 
			
		||||
      char nr[9];
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 7; i >= 0; i--) {
 | 
			
		||||
            nr[i] = hex[alpha%16];
 | 
			
		||||
            alpha /= 16;
 | 
			
		||||
            }
 | 
			
		||||
      nr[8] = 0;
 | 
			
		||||
      puts_pos(x,y,nr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void put_bin (int x, int y, byte xz)
 | 
			
		||||
							
								
								
									
										40
									
								
								kernel/include/sys/declarat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								kernel/include/sys/declarat.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
// Data type declarations
 | 
			
		||||
typedef unsigned char byte;
 | 
			
		||||
typedef unsigned short word;
 | 
			
		||||
typedef unsigned int dword;
 | 
			
		||||
 | 
			
		||||
/* This defines what the stack looks like after an ISR was running */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    unsigned int gs, fs, es, ds;      /* pushed the segs last */
 | 
			
		||||
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;  /* pushed by 'pusha' */
 | 
			
		||||
    unsigned int int_no, err_code;    /* our 'push byte #' and ecodes do this */
 | 
			
		||||
    unsigned int eip, cs, eflags, useresp, ss;   /* pushed by the processor automatically */ 
 | 
			
		||||
} regs;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Functions
 | 
			
		||||
void system_init();
 | 
			
		||||
void *memcpy(void *dest, const void *src, int count);
 | 
			
		||||
void *memset(void *dest, char val, int count);
 | 
			
		||||
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count);
 | 
			
		||||
int strlen (const char *str);
 | 
			
		||||
byte inportb (word _port);
 | 
			
		||||
byte inb (word _port);
 | 
			
		||||
void outportb (word _port, byte _data);
 | 
			
		||||
void outb (word _port, byte _data) ;
 | 
			
		||||
 | 
			
		||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
 | 
			
		||||
void gdt_install();
 | 
			
		||||
 | 
			
		||||
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
 | 
			
		||||
void idt_install();
 | 
			
		||||
 | 
			
		||||
void isrs_install();
 | 
			
		||||
 | 
			
		||||
void irq_install_handler(int irq, void (*handler)(regs *r));
 | 
			
		||||
void irq_uninstall_handler(int irq);
 | 
			
		||||
void irq_install();
 | 
			
		||||
void kb_handler(regs *r);
 | 
			
		||||
void reboot();
 | 
			
		||||
void kb_waitin();
 | 
			
		||||
							
								
								
									
										85
									
								
								kernel/include/system.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								kernel/include/system.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
#ifndef __SYSTEM_H
 | 
			
		||||
#define __SYSTEM_H
 | 
			
		||||
#include <sys/declarat.h>
 | 
			
		||||
 | 
			
		||||
#define true 1
 | 
			
		||||
#define false 0
 | 
			
		||||
 | 
			
		||||
byte *TextVideoRam;
 | 
			
		||||
volatile static int cursor_x, cursor_y;
 | 
			
		||||
int current_mode_width;
 | 
			
		||||
int current_mode_height;
 | 
			
		||||
 | 
			
		||||
void *memcpy(void *dest, const void *src, int count)
 | 
			
		||||
{
 | 
			
		||||
    const char *sp = (const char *)src;
 | 
			
		||||
    char *dp = (char *)dest;
 | 
			
		||||
    for(; count != 0; count--) *dp++ = *sp++;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *memset(void *dest, char val, int count)
 | 
			
		||||
{
 | 
			
		||||
    char *temp = (char *)dest;
 | 
			
		||||
    for( ; count != 0; count--) *temp++ = val;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
 | 
			
		||||
{
 | 
			
		||||
    unsigned short *temp = (unsigned short *)dest;
 | 
			
		||||
    for( ; count != 0; count--) *temp++ = val;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// strlen -- Get lenght of str
 | 
			
		||||
int strlen (const char *str)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; *str!=0; str++) i++;
 | 
			
		||||
      return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int strcmp(const char *pStr1, const char *pStr2)
 | 
			
		||||
{
 | 
			
		||||
    char c1, c2;
 | 
			
		||||
    int v;
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
        c1 = *pStr1++;
 | 
			
		||||
        c2 = *pStr2++;
 | 
			
		||||
        /* the casts are necessary when pStr1 is shorter & char is signed */
 | 
			
		||||
        v = (unsigned int)c1 - (unsigned int)c2;
 | 
			
		||||
    } while ((v == 0) && (c1 != '\0'));
 | 
			
		||||
 | 
			
		||||
    return v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte inportb (word _port) {
 | 
			
		||||
      byte rv;
 | 
			
		||||
      __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
 | 
			
		||||
      return rv;
 | 
			
		||||
}
 | 
			
		||||
byte inb (word _port) {
 | 
			
		||||
      byte rv;
 | 
			
		||||
      __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
 | 
			
		||||
      return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void iowait() {
 | 
			
		||||
      asm volatile ("outb %al, $0x80");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void outportb (word _port, byte _data) {
 | 
			
		||||
      __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
 | 
			
		||||
}
 | 
			
		||||
void outb (word _port, byte _data) {
 | 
			
		||||
      __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								kernel/kernel.bin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								kernel/kernel.bin
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										8
									
								
								kernel/kernel/epilogue.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								kernel/kernel/epilogue.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
void reboot()
 | 
			
		||||
{
 | 
			
		||||
    unsigned char good = 0x02;
 | 
			
		||||
    while ((good & 0x02) != 0)
 | 
			
		||||
        good = inportb(0x64);
 | 
			
		||||
    outportb(0x64, 0xFE);
 | 
			
		||||
    __asm__ __volatile__ ("hlt");
 | 
			
		||||
}
 | 
			
		||||
@@ -48,18 +48,25 @@ void irq_uninstall_handler (int irq)
 | 
			
		||||
*  Interrupt Controller (PICs - also called the 8259's) in
 | 
			
		||||
*  order to make IRQ0 to 15 be remapped to IDT entries 32 to
 | 
			
		||||
*  47 */
 | 
			
		||||
void irq_remap(void)
 | 
			
		||||
void irq_remap(int pic1, int pic2)
 | 
			
		||||
{
 | 
			
		||||
      // Send ICW1
 | 
			
		||||
      outportb(0x20, 0x11);
 | 
			
		||||
      outportb(0xA0, 0x11);
 | 
			
		||||
      outportb(0x21, 0x20);
 | 
			
		||||
      outportb(0xA1, 0x28);
 | 
			
		||||
      outportb(0x21, 0x04);
 | 
			
		||||
      outportb(0xA1, 0x02);
 | 
			
		||||
      
 | 
			
		||||
      // send ICW2
 | 
			
		||||
      outportb(0x21, pic1); // remap pics
 | 
			
		||||
      outportb(0xA1, pic2);
 | 
			
		||||
      
 | 
			
		||||
      // send ICW3
 | 
			
		||||
      outportb(0x21, 4);
 | 
			
		||||
      outportb(0xA1, 2);
 | 
			
		||||
      
 | 
			
		||||
      // Send ICW4
 | 
			
		||||
      outportb(0x21, 0x01);
 | 
			
		||||
      outportb(0xA1, 0x01);
 | 
			
		||||
      outportb(0x21, 0x0);
 | 
			
		||||
      outportb(0xA1, 0x0);
 | 
			
		||||
      
 | 
			
		||||
      outportb(0x21, 0x00);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* We first remap the interrupt controllers, and then we install
 | 
			
		||||
@@ -67,7 +74,7 @@ void irq_remap(void)
 | 
			
		||||
*  is just like installing the exception handlers */
 | 
			
		||||
void irq_install()
 | 
			
		||||
{
 | 
			
		||||
      irq_remap();
 | 
			
		||||
      irq_remap(32,40);
 | 
			
		||||
      
 | 
			
		||||
      idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
#include <console.h>
 | 
			
		||||
 | 
			
		||||
extern void isr0();
 | 
			
		||||
extern void isr1();
 | 
			
		||||
@@ -132,30 +131,30 @@ void fault_handler(regs *r)
 | 
			
		||||
        puts ("                              Blue Screen Of Death\n");
 | 
			
		||||
        int i; for (i = 79; i>=0; i--) putc('=');
 | 
			
		||||
        puts_pos_font (15, 2, "A fatal error has occured, CTA OS has been halted.", 0x01, 0x0C);
 | 
			
		||||
        puts_pos_font (10, 4, "gs", 0x01, 0x0B); put_hex(15, 4, r->gs);
 | 
			
		||||
        puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex(15, 5, r->fs);
 | 
			
		||||
        puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex(15, 6, r->es);
 | 
			
		||||
        puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex(15, 7, r->ds);
 | 
			
		||||
        puts_pos_font (10, 4, "gs", 0x01, 0x0B); put_hex_pos(15, 4, r->gs);
 | 
			
		||||
        puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex_pos(15, 5, r->fs);
 | 
			
		||||
        puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex_pos(15, 6, r->es);
 | 
			
		||||
        puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex_pos(15, 7, r->ds);
 | 
			
		||||
        
 | 
			
		||||
        puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex(45, 4, r->edi);
 | 
			
		||||
        puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex(45, 5, r->esi);
 | 
			
		||||
        puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex(45, 6, r->ebp);
 | 
			
		||||
        puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex(45, 7, r->esp);
 | 
			
		||||
        puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex_pos(45, 4, r->edi);
 | 
			
		||||
        puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex_pos(45, 5, r->esi);
 | 
			
		||||
        puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex_pos(45, 6, r->ebp);
 | 
			
		||||
        puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex_pos(45, 7, r->esp);
 | 
			
		||||
        
 | 
			
		||||
        puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex(15, 9, r->eax);
 | 
			
		||||
        puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex(15, 10, r->ebx);
 | 
			
		||||
        puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex(45, 9, r->ecx);
 | 
			
		||||
        puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex(45, 10, r->edx);
 | 
			
		||||
        puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex_pos(15, 9, r->eax);
 | 
			
		||||
        puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex_pos(15, 10, r->ebx);
 | 
			
		||||
        puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex_pos(45, 9, r->ecx);
 | 
			
		||||
        puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex_pos(45, 10, r->edx);
 | 
			
		||||
 | 
			
		||||
        puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex(17, 12, r->int_no);
 | 
			
		||||
        puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex(24, 14, r->err_code);
 | 
			
		||||
        puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex_pos(17, 12, r->int_no);
 | 
			
		||||
        puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex_pos(24, 14, r->err_code);
 | 
			
		||||
        puts_pos_font (10, 15, "Error msg: ", 0x01, 0x0B); puts_pos(24, 15, exception_messages[r->int_no]);
 | 
			
		||||
        
 | 
			
		||||
        puts_pos_font (10, 17, "eip", 0x01, 0x0B); put_hex(17, 17, r->eip);
 | 
			
		||||
        puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex(17, 18, r->cs);
 | 
			
		||||
        puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex(17, 19, r->eflags);
 | 
			
		||||
        puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex(17, 20, r->useresp);
 | 
			
		||||
        puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex(17, 21, r->ss);
 | 
			
		||||
        puts_pos_font (10, 17, "eip", 0x01, 0x0B); put_hex_pos(17, 17, r->eip);
 | 
			
		||||
        puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex_pos(17, 18, r->cs);
 | 
			
		||||
        puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex_pos(17, 19, r->eflags);
 | 
			
		||||
        puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex_pos(17, 20, r->useresp);
 | 
			
		||||
        puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex_pos(17, 21, r->ss);
 | 
			
		||||
        
 | 
			
		||||
        puts_pos_font (29, 24, "!!! System  Halted !!!", 0x01, 0x0C);
 | 
			
		||||
        for (;;);
 | 
			
		||||
							
								
								
									
										4
									
								
								kernel/kernel/memory.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								kernel/kernel/memory.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
extern unsigned long* read_cr0();
 | 
			
		||||
extern unsigned long* read_cr3();
 | 
			
		||||
extern void write_cr0(unsigned long* alpha);
 | 
			
		||||
extern void write_cr3(unsigned long* alpha);
 | 
			
		||||
							
								
								
									
										61
									
								
								kernel/kernel/prologue.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								kernel/kernel/prologue.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
#include "gdt.c"
 | 
			
		||||
#include "idt.c"
 | 
			
		||||
#include "isrs.c"
 | 
			
		||||
#include "irq.c"
 | 
			
		||||
 | 
			
		||||
void system_init()
 | 
			
		||||
{
 | 
			
		||||
  // Detect if color/monochrome screen
 | 
			
		||||
	char c = (*(volatile unsigned short*)0x410)&0x30;
 | 
			
		||||
	if (c==0x30) TextVideoRam = (byte *)0xb0000;
 | 
			
		||||
	else TextVideoRam = (byte *)0xb8000;
 | 
			
		||||
	
 | 
			
		||||
  // Reset cursor, use 80x25 text video mode
 | 
			
		||||
      current_mode_width = 80;
 | 
			
		||||
      current_mode_height = 25;
 | 
			
		||||
      cursor_x = cursor_y = 0;
 | 
			
		||||
 | 
			
		||||
  // Install GDT, IDT, ISRs and IRQs; Enable interrupts
 | 
			
		||||
      gdt_install();
 | 
			
		||||
      idt_install();
 | 
			
		||||
	isrs_install();
 | 
			
		||||
	irq_install();
 | 
			
		||||
      RTC_get_time();
 | 
			
		||||
      __asm__ __volatile__ ("sti");
 | 
			
		||||
	 
 | 
			
		||||
  // Install PIT timer
 | 
			
		||||
      timer_ticks = 0;
 | 
			
		||||
      timer_phase (100);
 | 
			
		||||
      irq_install_handler(0, timer_handler);
 | 
			
		||||
      
 | 
			
		||||
  // Install keyboard (part 1): install IRQ1 and start BAT test
 | 
			
		||||
      kb_modifier_status = 0;
 | 
			
		||||
      irq_install_handler(1, kb_handler);
 | 
			
		||||
      kb_waitin(); outportb(0x60, 0xFF);         // Reset kb
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
  // other drivers come here!!;
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
  // Install keyboard (part 2): BAT test results & set repeat rates
 | 
			
		||||
      byte temp;
 | 
			
		||||
      do temp = inportb(0x60);
 | 
			
		||||
      while (temp!=0xAA && temp!=0xFC);
 | 
			
		||||
            // KB failed BAT TEST
 | 
			
		||||
      if (temp == 0xFC) puts_font("\nKeyboard error: failed BAT test.", 0x07, 0x0C);
 | 
			
		||||
      kb_set_repeat(1, 11);
 | 
			
		||||
 | 
			
		||||
  // Install keyboard (part 3): set scancode set 2
 | 
			
		||||
      kb_set_scancodeset(2);  // Set new scancode set
 | 
			
		||||
 | 
			
		||||
      kb_waitin(); outportb(0x64, 0x20); // Get "Command byte"
 | 
			
		||||
      do {  temp = inportb(0x60);
 | 
			
		||||
      } while (temp==0xFA || temp==0xAA);
 | 
			
		||||
      
 | 
			
		||||
      temp &= 0xFF - (1<<6); // Set bit6 to 0: disable conversion
 | 
			
		||||
      kb_waitin(); outportb(0x64, 0x60); // Function to write cmd byte
 | 
			
		||||
      kb_waitin(); outportb(0x60, temp); // Send it
 | 
			
		||||
      memset(kb_array, 0, 16);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										135
									
								
								kernel/keyboard/key_list.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								kernel/keyboard/key_list.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
*0x00  Pause/Break
 | 
			
		||||
0x01  F9
 | 
			
		||||
0x02  F7
 | 
			
		||||
0x03  F5
 | 
			
		||||
0x04  F3
 | 
			
		||||
0x05  F1
 | 
			
		||||
0x06  F2
 | 
			
		||||
0x07  F12
 | 
			
		||||
0x08  Print Screen
 | 
			
		||||
0x09  F10
 | 
			
		||||
0x0A  F8
 | 
			
		||||
0x0B  F6
 | 
			
		||||
0x0C  F4
 | 
			
		||||
0x0D  Tab
 | 
			
		||||
0x0E  `~
 | 
			
		||||
0x0F  
 | 
			
		||||
 | 
			
		||||
0x10
 | 
			
		||||
0x11
 | 
			
		||||
0x12
 | 
			
		||||
0x13
 | 
			
		||||
0x14
 | 
			
		||||
0x15  Q
 | 
			
		||||
0x16  1!
 | 
			
		||||
0x17  
 | 
			
		||||
0x18  
 | 
			
		||||
0x19  
 | 
			
		||||
0x1A  Z
 | 
			
		||||
0x1B  S
 | 
			
		||||
0x1C  A
 | 
			
		||||
0x1D  W
 | 
			
		||||
0x1E  2@
 | 
			
		||||
0x1F  LeftWin
 | 
			
		||||
 | 
			
		||||
0x20  
 | 
			
		||||
0x21  C
 | 
			
		||||
0x22  X
 | 
			
		||||
0x23  D
 | 
			
		||||
0x24  E
 | 
			
		||||
0x25  4$
 | 
			
		||||
0x26  3#
 | 
			
		||||
0x27  RightWin
 | 
			
		||||
0x28  
 | 
			
		||||
0x29  Space
 | 
			
		||||
0x2A  V
 | 
			
		||||
0x2B  F
 | 
			
		||||
0x2C  T
 | 
			
		||||
0x2D  R
 | 
			
		||||
0x2E  5%
 | 
			
		||||
0x2F  Menu
 | 
			
		||||
 | 
			
		||||
0x30  
 | 
			
		||||
0x31  N
 | 
			
		||||
0x32  B
 | 
			
		||||
0x33  H
 | 
			
		||||
0x34  G
 | 
			
		||||
0x35  Y
 | 
			
		||||
0x36  6^
 | 
			
		||||
0x37  
 | 
			
		||||
0x38  
 | 
			
		||||
0x39  
 | 
			
		||||
0x3A  M
 | 
			
		||||
0x3B  J
 | 
			
		||||
0x3C  U
 | 
			
		||||
0x3D  7&
 | 
			
		||||
0x3E  8*
 | 
			
		||||
0x3F  
 | 
			
		||||
 | 
			
		||||
0x40  
 | 
			
		||||
0x41  ,<
 | 
			
		||||
0x42  K
 | 
			
		||||
0x43  I
 | 
			
		||||
0x44  O
 | 
			
		||||
0x45  0)
 | 
			
		||||
0x46  9(
 | 
			
		||||
0x47  
 | 
			
		||||
0x48  
 | 
			
		||||
0x49  .>
 | 
			
		||||
0x4A  /?
 | 
			
		||||
0x4B  L
 | 
			
		||||
0x4C  ;:
 | 
			
		||||
0x4D  P
 | 
			
		||||
0x4E  -_
 | 
			
		||||
0x4F  
 | 
			
		||||
 | 
			
		||||
0x50  
 | 
			
		||||
0x51  
 | 
			
		||||
0x52  '"
 | 
			
		||||
0x53  
 | 
			
		||||
0x54  [{
 | 
			
		||||
0x55  =+
 | 
			
		||||
0x56  
 | 
			
		||||
0x57  
 | 
			
		||||
0x58  
 | 
			
		||||
0x59  Numpad Enter
 | 
			
		||||
0x5A  Enter
 | 
			
		||||
0x5B  ]}
 | 
			
		||||
0x5C  
 | 
			
		||||
0x5D  \|
 | 
			
		||||
0x5E  End
 | 
			
		||||
0x5F  Left
 | 
			
		||||
 | 
			
		||||
0x60  Home
 | 
			
		||||
0x61  Insert
 | 
			
		||||
0x62  Delete
 | 
			
		||||
0x63  Down
 | 
			
		||||
0x64  Right
 | 
			
		||||
0x65  Up
 | 
			
		||||
0x66  Backspace
 | 
			
		||||
0x67  PageDown
 | 
			
		||||
0x68  PageUp
 | 
			
		||||
0x69  Numpad 1 (end)
 | 
			
		||||
0x6A  Numpad /
 | 
			
		||||
0x6B  Numpad 4 (left)
 | 
			
		||||
0x6C  Numpad 7 (Home)
 | 
			
		||||
0x6D  
 | 
			
		||||
0x6E  
 | 
			
		||||
0x6F  
 | 
			
		||||
 | 
			
		||||
0x70  Numpad 0 (insert)
 | 
			
		||||
0x71  Numpad . (del)
 | 
			
		||||
0x72  Numpad 2 (down)
 | 
			
		||||
0x73  Numpad 5
 | 
			
		||||
0x74  Numpad 6 (right)
 | 
			
		||||
0x75  Numpad 8 (up)
 | 
			
		||||
0x76  Esc
 | 
			
		||||
0x77  
 | 
			
		||||
0x78  F11
 | 
			
		||||
0x79  Numpad +
 | 
			
		||||
0x7A  Numpad 3 (pgdwn)
 | 
			
		||||
0x7B  Numpad -
 | 
			
		||||
0x7C  Numpad *
 | 
			
		||||
0x7D  Numpad 9 (pgup)
 | 
			
		||||
0x7E  
 | 
			
		||||
0x7F  
 | 
			
		||||
							
								
								
									
										60
									
								
								kernel/keyboard/keyb.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								kernel/keyboard/keyb.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void kb_test()
 | 
			
		||||
{
 | 
			
		||||
      byte temp=0, secs=0;
 | 
			
		||||
 | 
			
		||||
      puts("\nTHIS WILL TEST FEW COMMANDS OF THE PS/2 KEYBOARD.\n");
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
            puts("\nEcho... ");
 | 
			
		||||
            while ((inportb(0x64)&2)!=0);
 | 
			
		||||
            outportb(0x60, 0xEE);
 | 
			
		||||
/*            while ((inportb(0x64)&1)!=0);
 | 
			
		||||
            temp = inportb(0x60);
 | 
			
		||||
            putc_font('[', 0x07, 0x02);
 | 
			
		||||
            putc_font(hex[temp/16], 0x07, 0x02);
 | 
			
		||||
            putc_font(hex[temp%16], 0x07, 0x02);
 | 
			
		||||
            putc_font(']', 0x07, 0x02);*/
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
            puts("\nSet LEDs - SCROLL on... ");
 | 
			
		||||
            while ((inportb(0x64)&2)!=0);
 | 
			
		||||
            outportb(0x60, 0xED);
 | 
			
		||||
/*            while ((inportb(0x64)&2)!=0);
 | 
			
		||||
            outportb(0x60, 1);
 | 
			
		||||
            while ((inportb(0x64)&1)!=0);
 | 
			
		||||
            temp = inportb(0x60);*/
 | 
			
		||||
            putc_font('[', 0x07, 0x02);
 | 
			
		||||
            putc_font(hex[temp/16], 0x07, 0x02);
 | 
			
		||||
            putc_font(hex[temp%16], 0x07, 0x02);
 | 
			
		||||
            putc_font(']', 0x07, 0x02);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            puts("\nGet current scancode set... ");
 | 
			
		||||
            while ((inportb(0x64)&2)!=0);
 | 
			
		||||
            outportb(0x60, 0xF0);
 | 
			
		||||
            while ((inportb(0x64)&2)!=0);
 | 
			
		||||
            outportb(0x60, 0);
 | 
			
		||||
 | 
			
		||||
/*            while ((inportb(0x64)&1)!=0);
 | 
			
		||||
            temp = inportb(0x60);
 | 
			
		||||
            putc_font('[', 0x07, 0x02);
 | 
			
		||||
            putc_font(hex[temp/16], 0x07, 0x02);
 | 
			
		||||
            putc_font(hex[temp%16], 0x07, 0x02);
 | 
			
		||||
            putc_font(']', 0x07, 0x02);*/
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
            puts("\nTurning on 2 leds (don't know which ones :P)... ");
 | 
			
		||||
            while ((inportb(0x64)&2)!=0);
 | 
			
		||||
            outportb(0x60, 0xED);
 | 
			
		||||
            while ((inportb(0x64)&2)!=0);
 | 
			
		||||
            outportb(0x60, (byte)1|2);
 | 
			
		||||
 /*           while ((inportb(0x64)&1)!=0);
 | 
			
		||||
            temp = inportb(0x60);
 | 
			
		||||
            putc_font('[', 0x07, 0x02);
 | 
			
		||||
            putc_font(hex[temp/16], 0x07, 0x02);
 | 
			
		||||
            putc_font(hex[temp%16], 0x07, 0x02);
 | 
			
		||||
            putc_font(']', 0x07, 0x02);*/
 | 
			
		||||
      
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										179
									
								
								kernel/keyboard/keyus.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								kernel/keyboard/keyus.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
#include "keyus.h"
 | 
			
		||||
 | 
			
		||||
// kb_key_return 4-byte structure
 | 
			
		||||
typedef struct {
 | 
			
		||||
      byte status;
 | 
			
		||||
      byte lights;
 | 
			
		||||
      byte scancode;
 | 
			
		||||
      byte character;
 | 
			
		||||
} kb_key;
 | 
			
		||||
 | 
			
		||||
byte kb_array[16];
 | 
			
		||||
volatile static byte kb_newdata;
 | 
			
		||||
 | 
			
		||||
/*********DEBUG**************/
 | 
			
		||||
void kb_print_binary(int x, int y, byte what)
 | 
			
		||||
{
 | 
			
		||||
      char arr[9]; int i;
 | 
			
		||||
      for (i = 7; i>=0; i--, what/=2)
 | 
			
		||||
            arr[i] = (what%2) + '0';
 | 
			
		||||
            
 | 
			
		||||
      arr[8] = 0;
 | 
			
		||||
      
 | 
			
		||||
      puts_pos(x,y,arr);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
/*********DEBUG**************/
 | 
			
		||||
 | 
			
		||||
void kb_set_key(byte scancode, byte val)
 | 
			
		||||
{
 | 
			
		||||
      byte pos = scancode/8;
 | 
			
		||||
      byte offset = scancode%8;
 | 
			
		||||
      
 | 
			
		||||
      if (val) {
 | 
			
		||||
            kb_array[pos] |= 1<<offset;
 | 
			
		||||
            kb_newdata = scancode;
 | 
			
		||||
            }
 | 
			
		||||
      else kb_array[pos] &= 0xFF - (1<<offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
byte kb_get_key(byte scancode)
 | 
			
		||||
{
 | 
			
		||||
      byte pos = scancode/8;
 | 
			
		||||
      byte offset = scancode%8;
 | 
			
		||||
      return (kb_array[pos]&(1<<offset));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void kb_handler(regs *r) {
 | 
			
		||||
      byte scancode = inportb(0x60);
 | 
			
		||||
 | 
			
		||||
      switch (scancode) {
 | 
			
		||||
            case 0x00:                                      // Error 0x00
 | 
			
		||||
            case 0xFC:                                      // Diagnostics failed (MF kb)
 | 
			
		||||
            case 0xFD:                                      // Diagnostics failed (AT kb)
 | 
			
		||||
            case 0xFF: kb_waitin(); outportb(0x60, 0xF4);   // Error 0xFF
 | 
			
		||||
                        break;
 | 
			
		||||
            case 0xAA:                                      // BAT test successful.
 | 
			
		||||
            case 0xFA:                                      // ACKnowledge
 | 
			
		||||
            case 0xFE:                                      // Last command invalid or parity error
 | 
			
		||||
            case 0xEE: break;                              // Echo response
 | 
			
		||||
        // Gray or break
 | 
			
		||||
            case 0xE0: kb_prefix |= 1; break;
 | 
			
		||||
            case 0xE1: kb_prefix |= 4; break;
 | 
			
		||||
            case 0xF0: kb_prefix |= 2; break;
 | 
			
		||||
 | 
			
		||||
        // Alt, ctrl...
 | 
			
		||||
            case 0x11: if ((kb_prefix&1) == 0) {              // Left alt
 | 
			
		||||
                           if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<2;
 | 
			
		||||
                           else kb_modifier_status &= 0xFF - (1<<2);
 | 
			
		||||
                        }
 | 
			
		||||
                        else {                              // Right alt
 | 
			
		||||
                           if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<3;
 | 
			
		||||
                           else kb_modifier_status &= 0xFF - (1<<3);
 | 
			
		||||
                        }
 | 
			
		||||
                        kb_prefix = 0; break;
 | 
			
		||||
                        
 | 
			
		||||
            case 0x12: if ((kb_prefix&1) == 0) {              // Left shift
 | 
			
		||||
                           if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<0;
 | 
			
		||||
                           else kb_modifier_status &= 0xFF - (1<<0);
 | 
			
		||||
                        }
 | 
			
		||||
                        else {                              // Fake shift
 | 
			
		||||
                           if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<6;
 | 
			
		||||
                           else kb_modifier_status &= 0xFF - (1<<6);
 | 
			
		||||
                        }
 | 
			
		||||
                        kb_prefix = 0; break;
 | 
			
		||||
                        
 | 
			
		||||
            //TO ADD BELOW: pause/break byte1
 | 
			
		||||
            case 0x14: if (kb_prefix&4) {
 | 
			
		||||
                              if ((kb_prefix&2) == 0) kb_set_key (0, 1);
 | 
			
		||||
                              else kb_set_key (0, 0);
 | 
			
		||||
                              kb_prefix |= 8; break;
 | 
			
		||||
                              }
 | 
			
		||||
            
 | 
			
		||||
                        else if ((kb_prefix&1) == 0) {              // Left ctrl
 | 
			
		||||
                           if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<4;
 | 
			
		||||
                           else kb_modifier_status &= 0xFF - (1<<4);
 | 
			
		||||
                        }
 | 
			
		||||
                        else {                              // Right ctrl
 | 
			
		||||
                           if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<5;
 | 
			
		||||
                           else kb_modifier_status &= 0xFF - (1<<5);
 | 
			
		||||
                        }
 | 
			
		||||
                        kb_prefix = 0; break;
 | 
			
		||||
                        
 | 
			
		||||
            case 0x59:                                      // Right shift
 | 
			
		||||
                        if ((kb_prefix&2) == 0) kb_modifier_status |= 1<<1;
 | 
			
		||||
                        else kb_modifier_status &= 0xFF - (1<<1);
 | 
			
		||||
 | 
			
		||||
                        kb_prefix = 0; break;
 | 
			
		||||
                        
 | 
			
		||||
        // LEDs
 | 
			
		||||
            case 0x58: if ((kb_prefix&2) == 0) {
 | 
			
		||||
                  kb_lights_status ^= 4; kb_set_LEDs(kb_lights_status);
 | 
			
		||||
                  } kb_prefix = 0; break; // Caps
 | 
			
		||||
                  
 | 
			
		||||
            //TO ADD BELOW: pause/break byte2
 | 
			
		||||
            case 0x77:
 | 
			
		||||
                  if ((kb_prefix&4) && (kb_prefix&8)) kb_prefix=0;
 | 
			
		||||
                  else if ((kb_prefix&2) == 0) {
 | 
			
		||||
                  kb_lights_status ^= 2; kb_set_LEDs(kb_lights_status); 
 | 
			
		||||
                  } kb_prefix = 0; break; // Num
 | 
			
		||||
            case 0x7E: if ((kb_prefix&2) == 0) {
 | 
			
		||||
                  kb_lights_status ^= 1; kb_set_LEDs(kb_lights_status); 
 | 
			
		||||
                  } kb_prefix = 0; break; // Scroll
 | 
			
		||||
                        
 | 
			
		||||
            case 0x83: scancode = 0x02; // Put F7 under the 0x80 (128bit) barrier
 | 
			
		||||
                        
 | 
			
		||||
            default: 
 | 
			
		||||
                  // Remap gray keys
 | 
			
		||||
                  if (kb_prefix&1) switch (scancode) {
 | 
			
		||||
                        case 0x7C: scancode=0x08; break;    // PrintScreen
 | 
			
		||||
                        case 0x4A: scancode=0x6A; break;    // Numpad /
 | 
			
		||||
                        case 0x5A: scancode=0x59; break;    // Numpad Enter
 | 
			
		||||
                        case 0x69: scancode=0x5E; break;    // End
 | 
			
		||||
                        case 0x6B: scancode=0x5F; break;    // Left
 | 
			
		||||
                        case 0x6C: scancode=0x60; break;    // Home
 | 
			
		||||
                        case 0x70: scancode=0x61; break;    // Insert
 | 
			
		||||
                        case 0x71: scancode=0x62; break;    // Delete
 | 
			
		||||
                        case 0x72: scancode=0x63; break;    // Down
 | 
			
		||||
                        case 0x74: scancode=0x64; break;    // Right
 | 
			
		||||
                        case 0x75: scancode=0x65; break;    // Up
 | 
			
		||||
                        case 0x7A: scancode=0x67; break;    // PageDown
 | 
			
		||||
                        case 0x7D: scancode=0x68; break;    // PageUp
 | 
			
		||||
                        }
 | 
			
		||||
                  if ((kb_prefix&2) == 0) kb_set_key(scancode, 1);
 | 
			
		||||
                  else kb_set_key(scancode, 0);
 | 
			
		||||
                  
 | 
			
		||||
                  kb_prefix = 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();
 | 
			
		||||
            }
 | 
			
		||||
      
 | 
			
		||||
      outportb(0x20, 0x20);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
kb_key kb_getkey()
 | 
			
		||||
{
 | 
			
		||||
      kb_key ret;
 | 
			
		||||
      
 | 
			
		||||
      kb_newdata = 0xFF;
 | 
			
		||||
      while (kb_newdata==0xFF);              // wait for keypress
 | 
			
		||||
      
 | 
			
		||||
      ret.scancode = kb_newdata;          // Send scancode for non-chars
 | 
			
		||||
      ret.status = kb_modifier_status;    // Shift, ctrl... state
 | 
			
		||||
      ret.lights = kb_lights_status;      // Num, caps.... state
 | 
			
		||||
      
 | 
			
		||||
      if ((ret.status & 1) || (ret.status & 2)) // Shift is on
 | 
			
		||||
            ret.character = kbdus_map_shift[ret.scancode];
 | 
			
		||||
      else ret.character = kbdus_map[ret.scancode]; // Shift is off
 | 
			
		||||
      
 | 
			
		||||
      return ret;                         // And send it.
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										137
									
								
								kernel/keyboard/keyus.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								kernel/keyboard/keyus.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
void kb_set_LEDs(byte status);
 | 
			
		||||
void kb_set_repeat(byte rate, byte delay);
 | 
			
		||||
void kb_set_scancodeset(byte set);
 | 
			
		||||
 | 
			
		||||
char kbdus_map[] = {
 | 
			
		||||
      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, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
 | 
			
		||||
      0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0,
 | 
			
		||||
      0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0,
 | 
			
		||||
      0, 0, '\'', 0, '[', '=', 0, 0, 0, '\n', '\n', ']', 0, '\\', 0, 0,
 | 
			
		||||
      0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0,
 | 
			
		||||
      '0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
char kbdus_map_shift[] = {
 | 
			
		||||
      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, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
 | 
			
		||||
      0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0,
 | 
			
		||||
      0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0,
 | 
			
		||||
      0, 0, '\"', 0, '{', '+', 0, 0, 0, '\n', '\n', '}', 0, '|', 0, 0,
 | 
			
		||||
      0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0,
 | 
			
		||||
      '0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
 | 
			
		||||
      };
 | 
			
		||||
/* kb_modifier_status:
 | 
			
		||||
    BIT |    Description
 | 
			
		||||
    ----+-----------------------------------
 | 
			
		||||
     0  | Left Shift
 | 
			
		||||
     1  | Right Shift
 | 
			
		||||
     2  | Left Alt
 | 
			
		||||
     3  | Right Alt
 | 
			
		||||
     4  | Left CTRL
 | 
			
		||||
     5  | Right CTRL
 | 
			
		||||
     6  | Fake Shift     */
 | 
			
		||||
byte kb_modifier_status;
 | 
			
		||||
 | 
			
		||||
/* kb_modifier_status:
 | 
			
		||||
    BIT |    Description
 | 
			
		||||
    ----+-----------------------------------
 | 
			
		||||
     0  | Gray
 | 
			
		||||
     1  | Break code
 | 
			
		||||
     2  | 0xE1 (pause/break)
 | 
			
		||||
     3  | Recieved first byte from pause/break  */
 | 
			
		||||
byte kb_prefix;
 | 
			
		||||
 | 
			
		||||
/* kb_lights_status
 | 
			
		||||
    BIT |    Description
 | 
			
		||||
    ----+-----------------------------------
 | 
			
		||||
     0  | SCROLLOCK
 | 
			
		||||
     1  | NUMLOCK
 | 
			
		||||
     2  | CAPSLOCK */
 | 
			
		||||
byte kb_lights_status;
 | 
			
		||||
byte kb_scancode_set;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***************************************
 | 
			
		||||
 *       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(byte rate, byte delay)
 | 
			
		||||
{
 | 
			
		||||
      if (rate>3 || delay>31) return;
 | 
			
		||||
 | 
			
		||||
      byte out = rate<<5 | delay;
 | 
			
		||||
      while ((inportb(0x64)&2) != 0);
 | 
			
		||||
      outportb(0x60, 0xF3);
 | 
			
		||||
      while ((inportb(0x64)&2) != 0);
 | 
			
		||||
      outportb(0x60, out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***************************************
 | 
			
		||||
 *       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)
 | 
			
		||||
{
 | 
			
		||||
    while ((inportb (0x64)&2)!=0);
 | 
			
		||||
    outportb (0x60, 0xED);
 | 
			
		||||
  
 | 
			
		||||
    while ((inportb (0x64)&2)!=0);
 | 
			
		||||
    outportb (0x60, 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
 | 
			
		||||
 ***************************************/ 
 | 
			
		||||
void kb_set_scancodeset(byte set)
 | 
			
		||||
{
 | 
			
		||||
      //If ask for current scancode, tell kb handler what to expect
 | 
			
		||||
    if (set==0) kb_scancode_set = 4;
 | 
			
		||||
 | 
			
		||||
    while ((inportb (0x64)&2)!=0);
 | 
			
		||||
    outportb (0x60, 0xF0);
 | 
			
		||||
  
 | 
			
		||||
    while ((inportb (0x64)&2)!=0);
 | 
			
		||||
    outportb (0x60, set);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void kb_waitin()
 | 
			
		||||
{
 | 
			
		||||
      int fail_safe=200000;
 | 
			
		||||
      while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void kb_waitout()
 | 
			
		||||
{
 | 
			
		||||
      int fail_safe=200000;
 | 
			
		||||
      while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
 | 
			
		||||
}
 | 
			
		||||
@@ -442,8 +442,37 @@ irq_common_stub:
 | 
			
		||||
      add esp, 8
 | 
			
		||||
      iret
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
[global _read_cr0]
 | 
			
		||||
_read_cr0:
 | 
			
		||||
      mov eax, cr0
 | 
			
		||||
      retn
 | 
			
		||||
 | 
			
		||||
[global _write_cr0]
 | 
			
		||||
_write_cr0:
 | 
			
		||||
      push ebp
 | 
			
		||||
      mov ebp, esp
 | 
			
		||||
      mov eax, [ebp+8]
 | 
			
		||||
      mov cr0, eax
 | 
			
		||||
      pop ebp
 | 
			
		||||
      retn
 | 
			
		||||
      
 | 
			
		||||
[global _read_cr3]
 | 
			
		||||
_read_cr3:
 | 
			
		||||
      mov eax, cr3
 | 
			
		||||
      retn
 | 
			
		||||
      
 | 
			
		||||
[global _write_cr3]
 | 
			
		||||
_write_cr3:
 | 
			
		||||
      push ebp
 | 
			
		||||
      mov ebp, esp
 | 
			
		||||
      mov eax, [ebp+8]
 | 
			
		||||
      mov cr3, eax
 | 
			
		||||
      pop ebp
 | 
			
		||||
      retn
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
     
 | 
			
		||||
SECTION .bss
 | 
			
		||||
    resb 8192               ; This reserves 8KBytes of memory here
 | 
			
		||||
_sys_stack:
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								kernel/loader.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								kernel/loader.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										18
									
								
								kernel/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								kernel/main.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
#include <conio.h>
 | 
			
		||||
#include "clock/pictimer.c"
 | 
			
		||||
#include "keyboard/keyus.c"
 | 
			
		||||
#include "kernel/prologue.c"
 | 
			
		||||
#include "kernel/epilogue.c"
 | 
			
		||||
#include "shell/shell.c"
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
      system_init();
 | 
			
		||||
      
 | 
			
		||||
      shell();
 | 
			
		||||
 | 
			
		||||
      // do nothing
 | 
			
		||||
      for(;;);
 | 
			
		||||
      return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								kernel/main.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								kernel/main.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										122
									
								
								kernel/shell/apps.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								kernel/shell/apps.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,122 @@
 | 
			
		||||
const char *apps_lst[] = {
 | 
			
		||||
      "",
 | 
			
		||||
      "reboot",
 | 
			
		||||
      "osver",
 | 
			
		||||
      "date",
 | 
			
		||||
      "place",
 | 
			
		||||
      "cls",
 | 
			
		||||
      "memory"
 | 
			
		||||
      };
 | 
			
		||||
int apps_count = 7;
 | 
			
		||||
      
 | 
			
		||||
void apps_osver()
 | 
			
		||||
{
 | 
			
		||||
      puts("CTA OS v0.1");
 | 
			
		||||
      puts("\n(c) CTA 2010.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void apps_date()
 | 
			
		||||
{
 | 
			
		||||
      puts("Today is ");
 | 
			
		||||
      puts((char*)clock_weekdays[clock.weekday]);
 | 
			
		||||
      puts(", "); putc((clock.day/10)+'0');
 | 
			
		||||
      putc((clock.day%10)+'0');
 | 
			
		||||
      puts(" "); puts((char*)clock_months[clock.month]);
 | 
			
		||||
      puts(" "); putc((clock.century/10)+'0');
 | 
			
		||||
      putc((clock.century%10)+'0');
 | 
			
		||||
      putc((clock.year/10)+'0');
 | 
			
		||||
      putc((clock.year%10)+'0');
 | 
			
		||||
      putc('\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void apps_place()
 | 
			
		||||
{
 | 
			
		||||
      puts("On your desk, if you didn't notice... \n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void apps_clrscr()
 | 
			
		||||
{
 | 
			
		||||
      clrscr();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void apps_memory(const int pn, const char* param[])
 | 
			
		||||
{
 | 
			
		||||
      if (pn<3) {
 | 
			
		||||
            puts ("Correct syntax: memory [start_address] [end_address]     (in hex)\n");
 | 
			
		||||
            return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
      byte *start, *end;
 | 
			
		||||
      byte l1 = strlen(param[1]), l2 = strlen(param[2]);
 | 
			
		||||
      unsigned int a;
 | 
			
		||||
      int i; byte *count;
 | 
			
		||||
      
 | 
			
		||||
      a = 0;
 | 
			
		||||
      for(i = 0; i < l1; i++) {
 | 
			
		||||
            switch (param[1][i]) {
 | 
			
		||||
              case 'a':
 | 
			
		||||
              case 'A': a = a*16 + 10; break;
 | 
			
		||||
              case 'b': 
 | 
			
		||||
              case 'B': a = a*16 + 11; break;
 | 
			
		||||
              case 'c':
 | 
			
		||||
              case 'C': a = a*16 + 12; break;
 | 
			
		||||
              case 'd':
 | 
			
		||||
              case 'D': a = a*16 + 13; break;
 | 
			
		||||
              case 'e':
 | 
			
		||||
              case 'E': a = a*16 + 14; break;
 | 
			
		||||
              case 'f': 
 | 
			
		||||
              case 'F': a = a*16 + 15; break;
 | 
			
		||||
              
 | 
			
		||||
              default: if (!(param[1][i]>='0' && param[1][i]<='9')) {
 | 
			
		||||
                              puts ((char*)param[1]); puts(" is not a valid hex address.\n");
 | 
			
		||||
                              return;
 | 
			
		||||
                              }
 | 
			
		||||
                        a = a*16 + (param[1][i] - '0');
 | 
			
		||||
                        break;
 | 
			
		||||
              }
 | 
			
		||||
      }
 | 
			
		||||
      start = (byte *)a;
 | 
			
		||||
      
 | 
			
		||||
      a = 0;
 | 
			
		||||
      for(i = 0; i < l2; i++) {
 | 
			
		||||
            switch (param[2][i]) {
 | 
			
		||||
              case 'a':
 | 
			
		||||
              case 'A': a = a*16 + 10; break;
 | 
			
		||||
              case 'b': 
 | 
			
		||||
              case 'B': a = a*16 + 11; break;
 | 
			
		||||
              case 'c':
 | 
			
		||||
              case 'C': a = a*16 + 12; break;
 | 
			
		||||
              case 'd':
 | 
			
		||||
              case 'D': a = a*16 + 13; break;
 | 
			
		||||
              case 'e':
 | 
			
		||||
              case 'E': a = a*16 + 14; break;
 | 
			
		||||
              case 'f': 
 | 
			
		||||
              case 'F': a = a*16 + 15; break;
 | 
			
		||||
              
 | 
			
		||||
              default: if (!(param[2][i]>='0' && param[2][i]<='9')) {
 | 
			
		||||
                              puts ((char*)param[2]); puts(" is not a valid hex address.\n");
 | 
			
		||||
                              return;
 | 
			
		||||
                              }
 | 
			
		||||
                        a = a*16 + (param[2][i] - '0');
 | 
			
		||||
                        break;
 | 
			
		||||
              }
 | 
			
		||||
      }
 | 
			
		||||
      end = (byte *)a;
 | 
			
		||||
      
 | 
			
		||||
      while (start <= end) {
 | 
			
		||||
            put_hex ((unsigned int) start); puts(": ");
 | 
			
		||||
            
 | 
			
		||||
            for (count = start; count < start+16; count++) {
 | 
			
		||||
                  putc(hex[*count/16]); putc(hex[*count%16]);
 | 
			
		||||
                  putc(' ');
 | 
			
		||||
            }
 | 
			
		||||
            puts("  ");
 | 
			
		||||
            for (count = start; count < start+16; count++)
 | 
			
		||||
                  putc(*count);
 | 
			
		||||
            
 | 
			
		||||
            putc('\n');
 | 
			
		||||
            start+=16;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								kernel/shell/shell.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								kernel/shell/shell.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
#include <conio.h>
 | 
			
		||||
#include "apps.h"
 | 
			
		||||
 | 
			
		||||
void get_str(char *str, int len)
 | 
			
		||||
{
 | 
			
		||||
      kb_key alpha;
 | 
			
		||||
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; i<len-1 ; i++) {
 | 
			
		||||
            text_mode_cursor(cursor_x, cursor_y);
 | 
			
		||||
            alpha = kb_getkey();
 | 
			
		||||
            switch (alpha.character) {
 | 
			
		||||
                  case 0x00: --i; break;                    // Ignore null characters
 | 
			
		||||
                  case 0x7F: --i; break;
 | 
			
		||||
                  case '\b':                                // Backspace
 | 
			
		||||
                        if (i>0) {                          // Only backspace our string
 | 
			
		||||
                              if (--cursor_x < 0) {         // Begin of row - 1 = End of previous row
 | 
			
		||||
                                    cursor_x = 79; cursor_y--;
 | 
			
		||||
                              }
 | 
			
		||||
                              putc_pos(cursor_x, cursor_y, 0);
 | 
			
		||||
                              str[--i] = 0;
 | 
			
		||||
                        }
 | 
			
		||||
                        i--; break;
 | 
			
		||||
                        
 | 
			
		||||
                  case '\n': str[i]=0; putc('\n'); return;
 | 
			
		||||
                        
 | 
			
		||||
                  default: putc(alpha.character);
 | 
			
		||||
                        str[i] = alpha.character;
 | 
			
		||||
                        str[i+1] = 0;
 | 
			
		||||
                        break;
 | 
			
		||||
                  }
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void shell()
 | 
			
		||||
{
 | 
			
		||||
      char str[256];
 | 
			
		||||
	char* param[16];
 | 
			
		||||
      int i, len, params=0;
 | 
			
		||||
 | 
			
		||||
      set_default_colors (0x07, 0x04);
 | 
			
		||||
      clrscr();
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      for (;;) {
 | 
			
		||||
            puts("\n] ");
 | 
			
		||||
            get_str(str, 256);
 | 
			
		||||
 | 
			
		||||
			len = strlen(str);
 | 
			
		||||
 | 
			
		||||
			// Ignore spaces in front of command
 | 
			
		||||
			i=0; params = 0;
 | 
			
		||||
			while (str[i] == ' ') i++;
 | 
			
		||||
			param[params] = str+i; params++; i++;  // Parameter 0 = app itself
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			for (; i < len && params<16; i++) {
 | 
			
		||||
				if (str[i] == ' ') str[i]=0;
 | 
			
		||||
 | 
			
		||||
				if (str[i] != 0 && str[i-1]==0) {
 | 
			
		||||
					param[params] = str+i; params++;
 | 
			
		||||
				}
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (i = 0; strcmp(apps_lst[i], param[0])!=0 && i<apps_count; i++);
 | 
			
		||||
            switch (i) {
 | 
			
		||||
                  case 0: puts("You must enter a command!\n"); break;
 | 
			
		||||
                  case 1: reboot();
 | 
			
		||||
                  case 2: apps_osver(); break;
 | 
			
		||||
                  case 3: apps_date(); break;
 | 
			
		||||
                  case 4: apps_place(); break;
 | 
			
		||||
                  case 5: apps_clrscr(); break;
 | 
			
		||||
                  case 6: apps_memory(params, (const char**)param); break;
 | 
			
		||||
                  default: puts("Invalid function: "); puts(param[0]); 
 | 
			
		||||
					  putc('\n');
 | 
			
		||||
					  break;
 | 
			
		||||
            }
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										209
									
								
								keyus.c
									
									
									
									
									
								
							
							
						
						
									
										209
									
								
								keyus.c
									
									
									
									
									
								
							@@ -1,209 +0,0 @@
 | 
			
		||||
unsigned char kbdus[128] =
 | 
			
		||||
{
 | 
			
		||||
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
 | 
			
		||||
  '9', '0', '-', '=', '\b',	/* Backspace */
 | 
			
		||||
  '\t',			/* Tab */
 | 
			
		||||
  'q', 'w', 'e', 'r',	/* 19 */
 | 
			
		||||
  't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',	/* Enter key */
 | 
			
		||||
    0,			/* 29   - Control */
 | 
			
		||||
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',	/* 39 */
 | 
			
		||||
 '\'', '`',   0,		/* Left shift */
 | 
			
		||||
 '\\', 'z', 'x', 'c', 'v', 'b', 'n',			/* 49 */
 | 
			
		||||
  'm', ',', '.', '/',   0,				/* Right shift */
 | 
			
		||||
  '*',
 | 
			
		||||
    0,	/* Alt */
 | 
			
		||||
  ' ',	/* Space bar */
 | 
			
		||||
    0,	/* Caps lock */
 | 
			
		||||
    0,	/* 59 - F1 key ... > */
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,	/* < ... F10 */
 | 
			
		||||
    0,	/* 69 - Num lock*/
 | 
			
		||||
    0,	/* Scroll Lock */
 | 
			
		||||
    0,	/* Home key */
 | 
			
		||||
    0,	/* Up Arrow */
 | 
			
		||||
    0,	/* Page Up */
 | 
			
		||||
  '-',
 | 
			
		||||
    0,	/* Left Arrow */
 | 
			
		||||
    0,
 | 
			
		||||
    0,	/* Right Arrow */
 | 
			
		||||
  '+',
 | 
			
		||||
    0,	/* 79 - End key*/
 | 
			
		||||
    0,	/* Down Arrow */
 | 
			
		||||
    0,	/* Page Down */
 | 
			
		||||
    0,	/* Insert Key */
 | 
			
		||||
    0,	/* Delete Key */
 | 
			
		||||
    0,   0,   0,
 | 
			
		||||
    0,	/* F11 Key */
 | 
			
		||||
    0,	/* F12 Key */
 | 
			
		||||
    0,	/* All other keys are undefined */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned char kbdus_shift[128] =
 | 
			
		||||
{
 | 
			
		||||
    0,  27, '!', '@', '#', '$', '%', '^', '&', '*',	/* 9 */
 | 
			
		||||
  '(', ')', '_', '+', '\b',	/* Backspace */
 | 
			
		||||
  '\t',			/* Tab */
 | 
			
		||||
  'Q', 'W', 'E', 'R',	/* 19 */
 | 
			
		||||
  'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',	/* Enter key */
 | 
			
		||||
    0,			/* 29   - Control */
 | 
			
		||||
  'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',	/* 39 */
 | 
			
		||||
 '\"', '~',   0,		/* Left shift */
 | 
			
		||||
 '|', 'Z', 'X', 'C', 'V', 'B', 'N',			/* 49 */
 | 
			
		||||
  'M', '<', '>', '?',   0,				/* Right shift */
 | 
			
		||||
  '*',
 | 
			
		||||
    0,	/* Alt */
 | 
			
		||||
  ' ',	/* Space bar */
 | 
			
		||||
    0,	/* Caps lock */
 | 
			
		||||
    0,	/* 59 - F1 key ... > */
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,	/* < ... F10 */
 | 
			
		||||
    0,	/* 69 - Num lock*/
 | 
			
		||||
    0,	/* Scroll Lock */
 | 
			
		||||
    0,	/* Home key */
 | 
			
		||||
    0,	/* Up Arrow */
 | 
			
		||||
    0,	/* Page Up */
 | 
			
		||||
  '-',
 | 
			
		||||
    0,	/* Left Arrow */
 | 
			
		||||
    0,
 | 
			
		||||
    0,	/* Right Arrow */
 | 
			
		||||
  '+',
 | 
			
		||||
    0,	/* 79 - End key*/
 | 
			
		||||
    0,	/* Down Arrow */
 | 
			
		||||
    0,	/* Page Down */
 | 
			
		||||
    0,	/* Insert Key */
 | 
			
		||||
    0,	/* Delete Key */
 | 
			
		||||
    0,   0,   0,
 | 
			
		||||
    0,	/* F11 Key */
 | 
			
		||||
    0,	/* F12 Key */
 | 
			
		||||
    0,	/* All other keys are undefined */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* kb_modifier_status:
 | 
			
		||||
    BIT |    Description
 | 
			
		||||
    ----+-----------------------------------
 | 
			
		||||
     0  | Left Shift
 | 
			
		||||
     1  | Right Shift
 | 
			
		||||
     2  | Left Alt
 | 
			
		||||
     3  | Right Alt
 | 
			
		||||
     4  | Left CTRL
 | 
			
		||||
     5  | Right CTRL
 | 
			
		||||
     6  | Fake Shift
 | 
			
		||||
     7  | Special     */
 | 
			
		||||
unsigned char kb_modifier_status;
 | 
			
		||||
 | 
			
		||||
/* kb_lights_status
 | 
			
		||||
    BIT |    Description
 | 
			
		||||
    ----+-----------------------------------
 | 
			
		||||
     0  | SCROLLOCK
 | 
			
		||||
     1  | NUMLOCK
 | 
			
		||||
     2  | CAPSLOCK */
 | 
			
		||||
unsigned char kb_lights_status;
 | 
			
		||||
 | 
			
		||||
void kb_update_LED()
 | 
			
		||||
{
 | 
			
		||||
    while ((inportb (0x64)&2)!=0);
 | 
			
		||||
    outportb (0x60, 0xED);
 | 
			
		||||
  
 | 
			
		||||
    while ((inportb (0x64)&2)!=0);
 | 
			
		||||
    outportb (0x60, kb_lights_status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* kb_toggle_LED
 | 
			
		||||
 Toggle NUM/CAPS/SCROLL LOCK LEDs. 0 to ignore. If all 0, reset; */
 | 
			
		||||
void kb_toggle_LED(int NUM, int CAPS, int SCROLL)
 | 
			
		||||
{
 | 
			
		||||
      if (NUM) kb_lights_status ^= 1<<1;
 | 
			
		||||
      if (CAPS) kb_lights_status ^= 1<<2;
 | 
			
		||||
      if (SCROLL) kb_lights_status ^= 1;
 | 
			
		||||
      if ((!NUM) && (!CAPS) && (!SCROLL)) kb_lights_status = 0;
 | 
			
		||||
      kb_update_LED();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
byte prev, scancode;
 | 
			
		||||
void kb_handler(regs *r) {
 | 
			
		||||
      scancode = inportb(0x60);
 | 
			
		||||
     
 | 
			
		||||
      puts_pos(0, 0, "Key Pressed ");put_hex(30, 0, scancode);
 | 
			
		||||
 | 
			
		||||
      switch (scancode) {
 | 
			
		||||
        // Special
 | 
			
		||||
        case 0x0E: kb_modifier_status |= 1<<7;
 | 
			
		||||
                    break;
 | 
			
		||||
            
 | 
			
		||||
        // Left Shift or fake shift make
 | 
			
		||||
        case 0x2A: if (kb_modifier_status && 128) kb_modifier_status |= 1<<6;
 | 
			
		||||
                    else kb_modifier_status |= 1;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Left Shift or fake shift release
 | 
			
		||||
        case 0xAA: if (kb_modifier_status && 128) kb_modifier_status &= (1<<6) ^0xFF;
 | 
			
		||||
                    else kb_modifier_status &= 1 ^0xFF;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Right Shift make
 | 
			
		||||
        case 0x36: kb_modifier_status |= 1<<1;
 | 
			
		||||
                    break;
 | 
			
		||||
        
 | 
			
		||||
        // Right shift release
 | 
			
		||||
        case 0xB6: kb_modifier_status &= (1<<1) ^0xFF;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Left Alt or Right Alt make
 | 
			
		||||
        case 0x38: if (kb_modifier_status && 128) kb_modifier_status |= 1<<3;
 | 
			
		||||
                    else kb_modifier_status |= 1<<2;
 | 
			
		||||
                    break;
 | 
			
		||||
        
 | 
			
		||||
        // Left Alt or Right Alt release            
 | 
			
		||||
        case 0xB8: if (kb_modifier_status && 128) kb_modifier_status &= (1<<3) ^0xFF;
 | 
			
		||||
                    else kb_modifier_status &= (1<<2) ^0xFF;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Left Ctrl or Right Ctrl make
 | 
			
		||||
        case 0x1D: if (kb_modifier_status && 128) kb_modifier_status |= 1<<5;
 | 
			
		||||
                    else kb_modifier_status |= 1<<4;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Left Ctrl or Right Ctrl release
 | 
			
		||||
        case 0x9D: if (kb_modifier_status && 128) kb_modifier_status &= (1<<5) ^0xFF;
 | 
			
		||||
                    else kb_modifier_status &= (1<<5) ^0xFF;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
        // Caps, Num and Scroll (in this order)
 | 
			
		||||
        case 0x3A: kb_toggle_LED (0,1,0); break;
 | 
			
		||||
        case 0x45: kb_toggle_LED (1,0,0); break;
 | 
			
		||||
        case 0x46: kb_toggle_LED (0,0,1); break;
 | 
			
		||||
 | 
			
		||||
        default: if (scancode & 0x80) break;
 | 
			
		||||
                  if (scancode != prev) kb_modifier_status &= (1<<7) ^0xFF;
 | 
			
		||||
                  if ((kb_modifier_status && 1) || (kb_modifier_status && 2))
 | 
			
		||||
                        putc_pos(50, 0, kbdus_shift[scancode]);
 | 
			
		||||
                  else putc_pos (50, 0, kbdus[scancode]);
 | 
			
		||||
                  break;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      outportb(0x20, 0x20);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char kb_getch()
 | 
			
		||||
{
 | 
			
		||||
      regs *r = 0;
 | 
			
		||||
      do {
 | 
			
		||||
            prev = scancode; kb_handler(r); }
 | 
			
		||||
      while (prev == scancode || prev+0x80 == scancode);
 | 
			
		||||
      
 | 
			
		||||
            
 | 
			
		||||
      if ((kb_modifier_status && 1) || (kb_modifier_status && 2))
 | 
			
		||||
                  return kbdus_shift[scancode];
 | 
			
		||||
 | 
			
		||||
      return kbdus[scancode];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void kb_get_status()
 | 
			
		||||
{
 | 
			
		||||
      byte a = inportb(0x64);
 | 
			
		||||
      puts_pos(0, 8, "KeyBrd Status: ");
 | 
			
		||||
      put_bin(0, 9, a);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								main.c
									
									
									
									
									
								
							@@ -1,65 +0,0 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
#include <console.h>
 | 
			
		||||
#include "gdt.c"
 | 
			
		||||
#include "idt.c"
 | 
			
		||||
#include "isrs.c"
 | 
			
		||||
#include "irq.c"
 | 
			
		||||
#include "timer.c"
 | 
			
		||||
#include "keyus.c"
 | 
			
		||||
#include "init.c"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*void put_line_scroll(int line, char c)
 | 
			
		||||
{
 | 
			
		||||
      int i = 0;
 | 
			
		||||
      while (TextVideoRam[2*(80*line+i)] != 0 && i<=80) ++i;
 | 
			
		||||
      if (i>78) {
 | 
			
		||||
            memcpy(TextVideoRam + (2*80*line), TextVideoRam + (2*80*line) + 2, (i+1)*2);
 | 
			
		||||
            }
 | 
			
		||||
      putc_pos(i, line, c);
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
      system_init();
 | 
			
		||||
      set_default_colors (0x07, 0x04);
 | 
			
		||||
      clrscr();
 | 
			
		||||
      
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i=0;i<80;i++) putc_pos_font (i, 0, ' ', 0x02, 0x0F);
 | 
			
		||||
      puts_pos_font (60, 0, "Uptime:", 0x02, 0x0E); cursor_y++;
 | 
			
		||||
 | 
			
		||||
      // Do other stuff
 | 
			
		||||
      puts ("Testing puts...\nAnd this shoudl be new line\n");
 | 
			
		||||
      puts_font ("And this should be colored in another color ", 0x02, 0x0F);
 | 
			
		||||
      puts ("<- colored font should be right about heree");
 | 
			
		||||
      
 | 
			
		||||
      puts_pos (0, 23, "This text should be starting in position (0, 23)");
 | 
			
		||||
      puts_pos_font (0, 23, "THIS", 0x00, 0x09);
 | 
			
		||||
      
 | 
			
		||||
      puts_pos (5, 20, "<- The cursor should be blinking right here");
 | 
			
		||||
      putc_pos_font (3, 20, 0, 0x04, 0x0F);
 | 
			
		||||
      text_mode_cursor(3, 20);     
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      while (1) {
 | 
			
		||||
            kb_get_status();
 | 
			
		||||
 | 
			
		||||
            put_bin(60, 15, kb_modifier_status);
 | 
			
		||||
            puts_pos_font (60, 16, "LShift", 0x07, 0x08 - (kb_modifier_status&1)*0x06);
 | 
			
		||||
            puts_pos_font (60, 17, "RShift", 0x07, 0x08 - (kb_modifier_status&2)*0x06);
 | 
			
		||||
            puts_pos_font (60, 18, "LAlt", 0x07, 0x08 - (kb_modifier_status&4)*0x06);
 | 
			
		||||
            puts_pos_font (60, 19, "RAlt", 0x07, 0x08 - (kb_modifier_status&8)*0x06);
 | 
			
		||||
            puts_pos_font (60, 20, "LCtrl", 0x07, 0x08 - (kb_modifier_status&16)*0x06);
 | 
			
		||||
            puts_pos_font (60, 21, "RCtrl", 0x07, 0x08 - (kb_modifier_status&32)*0x06);
 | 
			
		||||
            puts_pos_font (60, 22, "FakeShift", 0x07, 0x08 - (kb_modifier_status&64)*0x06);
 | 
			
		||||
            puts_pos_font (60, 23, "Special", 0x07, 0x08 - (kb_modifier_status&128)*0x06);
 | 
			
		||||
            
 | 
			
		||||
            putc (kb_getch());
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // do nothing
 | 
			
		||||
      for(;;);
 | 
			
		||||
      return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								stage1/MAKE.PIF
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								stage1/MAKE.PIF
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										314
									
								
								stage1/bootload.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										314
									
								
								stage1/bootload.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,314 @@
 | 
			
		||||
 | 
			
		||||
;*********************************************
 | 
			
		||||
;	Boot1.asm
 | 
			
		||||
;		- A Simple Bootloader
 | 
			
		||||
;
 | 
			
		||||
;	Operating Systems Development Series
 | 
			
		||||
;*********************************************
 | 
			
		||||
 | 
			
		||||
bits	16						; we are in 16 bit real mode
 | 
			
		||||
 | 
			
		||||
org	0						; we will set regisers later
 | 
			
		||||
 | 
			
		||||
start:	jmp	main					; jump to start of bootloader
 | 
			
		||||
 | 
			
		||||
;*********************************************
 | 
			
		||||
;	BIOS Parameter Block
 | 
			
		||||
;*********************************************
 | 
			
		||||
 | 
			
		||||
; BPB Begins 3 bytes from start. We do a far jump, which is 3 bytes in size.
 | 
			
		||||
; If you use a short jump, add a "nop" after it to offset the 3rd byte.
 | 
			
		||||
 | 
			
		||||
bpbOEM			db "CTA OS  "			; OEM identifier (Cannot exceed 8 bytes!)
 | 
			
		||||
bpbBytesPerSector:  	DW 512
 | 
			
		||||
bpbSectorsPerCluster: 	DB 1
 | 
			
		||||
bpbReservedSectors: 	DW 1
 | 
			
		||||
bpbNumberOfFATs: 	      DB 2
 | 
			
		||||
bpbRootEntries: 	      DW 224
 | 
			
		||||
bpbTotalSectors: 	      DW 2880
 | 
			
		||||
bpbMedia: 		      DB 0xf8  ;; 0xF1
 | 
			
		||||
bpbSectorsPerFAT: 	DW 9
 | 
			
		||||
bpbSectorsPerTrack: 	DW 18
 | 
			
		||||
bpbHeadsPerCylinder: 	DW 2
 | 
			
		||||
bpbHiddenSectors: 	DD 0
 | 
			
		||||
bpbTotalSectorsBig:     DD 0
 | 
			
		||||
bsDriveNumber: 	      DB 0
 | 
			
		||||
bsUnused: 		      DB 0
 | 
			
		||||
bsExtBootSignature: 	DB 0x29
 | 
			
		||||
bsSerialNumber:	      DD 0xa0a1a2a3
 | 
			
		||||
bsVolumeLabel: 	      DB "CTA FLOPPY "
 | 
			
		||||
bsFileSystem: 	      DB "FAT12   "
 | 
			
		||||
 | 
			
		||||
;************************************************;
 | 
			
		||||
;	Prints a string
 | 
			
		||||
;	DS=>SI: 0 terminated string
 | 
			
		||||
;************************************************;
 | 
			
		||||
Print:
 | 
			
		||||
			lodsb				; load next byte from string from SI to AL
 | 
			
		||||
			or	al, al			; Does AL=0?
 | 
			
		||||
			jz	PrintDone		; Yep, null terminator found-bail out
 | 
			
		||||
			mov	ah, 0eh			; Nope-Print the character
 | 
			
		||||
			int	10h
 | 
			
		||||
			jmp	Print			; Repeat until null terminator found
 | 
			
		||||
	PrintDone:
 | 
			
		||||
			ret				; we are done, so return
 | 
			
		||||
 | 
			
		||||
;************************************************;
 | 
			
		||||
; Reads a series of sectors
 | 
			
		||||
; CX=>Number of sectors to read
 | 
			
		||||
; AX=>Starting sector
 | 
			
		||||
; ES:BX=>Buffer to read to
 | 
			
		||||
;************************************************;
 | 
			
		||||
 | 
			
		||||
ReadSectors:
 | 
			
		||||
     .MAIN:
 | 
			
		||||
          mov     di, 0x0005                          ; five retries for error
 | 
			
		||||
     .SECTORLOOP:
 | 
			
		||||
          push    ax
 | 
			
		||||
          push    bx
 | 
			
		||||
          push    cx
 | 
			
		||||
          call    LBACHS                              ; convert starting sector to CHS
 | 
			
		||||
          mov     ah, 0x02                            ; BIOS read sector
 | 
			
		||||
          mov     al, 0x01                            ; read one sector
 | 
			
		||||
          mov     ch, BYTE [absoluteTrack]            ; track
 | 
			
		||||
          mov     cl, BYTE [absoluteSector]           ; sector
 | 
			
		||||
          mov     dh, BYTE [absoluteHead]             ; head
 | 
			
		||||
          mov     dl, BYTE [bsDriveNumber]            ; drive
 | 
			
		||||
          int     0x13                                ; invoke BIOS
 | 
			
		||||
          jnc     .SUCCESS                            ; test for read error
 | 
			
		||||
          xor     ax, ax                              ; BIOS reset disk
 | 
			
		||||
          int     0x13                                ; invoke BIOS
 | 
			
		||||
          dec     di                                  ; decrement error counter
 | 
			
		||||
          pop     cx
 | 
			
		||||
          pop     bx
 | 
			
		||||
          pop     ax
 | 
			
		||||
          jnz     .SECTORLOOP                         ; attempt to read again
 | 
			
		||||
          int     0x18
 | 
			
		||||
     .SUCCESS:
 | 
			
		||||
          mov     si, msgProgress
 | 
			
		||||
          call    Print
 | 
			
		||||
          pop     cx
 | 
			
		||||
          pop     bx
 | 
			
		||||
          pop     ax
 | 
			
		||||
          add     bx, WORD [bpbBytesPerSector]        ; queue next buffer
 | 
			
		||||
          inc     ax                                  ; queue next sector
 | 
			
		||||
          loop    .MAIN                               ; read next sector
 | 
			
		||||
          ret
 | 
			
		||||
 | 
			
		||||
;************************************************;
 | 
			
		||||
; Convert CHS to LBA
 | 
			
		||||
; LBA = (cluster - 2) * sectors per cluster
 | 
			
		||||
;************************************************;
 | 
			
		||||
 | 
			
		||||
ClusterLBA:
 | 
			
		||||
          sub     ax, 0x0002                          ; zero base cluster number
 | 
			
		||||
          xor     cx, cx
 | 
			
		||||
          mov     cl, BYTE [bpbSectorsPerCluster]     ; convert byte to word
 | 
			
		||||
          mul     cx
 | 
			
		||||
          add     ax, WORD [datasector]               ; base data sector
 | 
			
		||||
          ret
 | 
			
		||||
     
 | 
			
		||||
;************************************************;
 | 
			
		||||
; Convert LBA to CHS
 | 
			
		||||
; AX=>LBA Address to convert
 | 
			
		||||
;
 | 
			
		||||
; absolute sector = (logical sector / sectors per track) + 1
 | 
			
		||||
; absolute head   = (logical sector / sectors per track) MOD number of heads
 | 
			
		||||
; absolute track  = logical sector / (sectors per track * number of heads)
 | 
			
		||||
;
 | 
			
		||||
;************************************************;
 | 
			
		||||
 | 
			
		||||
LBACHS:
 | 
			
		||||
          xor     dx, dx                              ; prepare dx:ax for operation
 | 
			
		||||
          div     WORD [bpbSectorsPerTrack]           ; calculate
 | 
			
		||||
          inc     dl                                  ; adjust for sector 0
 | 
			
		||||
          mov     BYTE [absoluteSector], dl
 | 
			
		||||
          xor     dx, dx                              ; prepare dx:ax for operation
 | 
			
		||||
          div     WORD [bpbHeadsPerCylinder]          ; calculate
 | 
			
		||||
          mov     BYTE [absoluteHead], dl
 | 
			
		||||
          mov     BYTE [absoluteTrack], al
 | 
			
		||||
          ret
 | 
			
		||||
 | 
			
		||||
;*********************************************
 | 
			
		||||
;	Bootloader Entry Point
 | 
			
		||||
;*********************************************
 | 
			
		||||
 | 
			
		||||
main:
 | 
			
		||||
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     ; code located at 0000:7C00, adjust segment registers
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     
 | 
			
		||||
          cli						; disable interrupts
 | 
			
		||||
          mov     ax, 0x07C0				; setup registers to point to our segment
 | 
			
		||||
          mov     ds, ax
 | 
			
		||||
          mov     es, ax
 | 
			
		||||
          mov     fs, ax
 | 
			
		||||
          mov     gs, ax
 | 
			
		||||
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     ; create stack
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     
 | 
			
		||||
          mov     ax, 0x0000				; set the stack
 | 
			
		||||
          mov     ss, ax
 | 
			
		||||
          mov     sp, 0xFFFF
 | 
			
		||||
          sti						; restore interrupts
 | 
			
		||||
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     ; Display loading message
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     
 | 
			
		||||
          mov     si, msgLoading
 | 
			
		||||
          call    Print
 | 
			
		||||
          
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     ; Load root directory table
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
     LOAD_ROOT:
 | 
			
		||||
     
 | 
			
		||||
     ; compute size of root directory and store in "cx"
 | 
			
		||||
     
 | 
			
		||||
          xor     cx, cx
 | 
			
		||||
          xor     dx, dx
 | 
			
		||||
          mov     ax, 0x0020                           ; 32 byte directory entry
 | 
			
		||||
          mul     WORD [bpbRootEntries]                ; total size of directory
 | 
			
		||||
          div     WORD [bpbBytesPerSector]             ; sectors used by directory
 | 
			
		||||
          xchg    ax, cx
 | 
			
		||||
          
 | 
			
		||||
     ; compute location of root directory and store in "ax"
 | 
			
		||||
     
 | 
			
		||||
          mov     al, BYTE [bpbNumberOfFATs]            ; number of FATs
 | 
			
		||||
          mul     WORD [bpbSectorsPerFAT]               ; sectors used by FATs
 | 
			
		||||
          add     ax, WORD [bpbReservedSectors]         ; adjust for bootsector
 | 
			
		||||
          mov     WORD [datasector], ax                 ; base of root directory
 | 
			
		||||
          add     WORD [datasector], cx
 | 
			
		||||
          
 | 
			
		||||
     ; read root directory into memory (7C00:0200)
 | 
			
		||||
     
 | 
			
		||||
          mov     bx, 0x0200                            ; copy root dir above bootcode
 | 
			
		||||
          call    ReadSectors
 | 
			
		||||
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     ; Find stage 2
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
     ; browse root directory for binary image
 | 
			
		||||
          mov     cx, WORD [bpbRootEntries]             ; load loop counter
 | 
			
		||||
          mov     di, 0x0200                            ; locate first root entry
 | 
			
		||||
     .LOOP:
 | 
			
		||||
          push    cx
 | 
			
		||||
          mov     cx, 0x000B                            ; eleven character name
 | 
			
		||||
          mov     si, ImageName                         ; image name to find
 | 
			
		||||
          push    di
 | 
			
		||||
     rep  cmpsb                                         ; test for entry match
 | 
			
		||||
          pop     di
 | 
			
		||||
          je      LOAD_FAT
 | 
			
		||||
          pop     cx
 | 
			
		||||
          add     di, 0x0020                            ; queue next directory entry
 | 
			
		||||
          loop    .LOOP
 | 
			
		||||
          jmp     FAILURE
 | 
			
		||||
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     ; Load FAT
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
     LOAD_FAT:
 | 
			
		||||
     
 | 
			
		||||
     ; save starting cluster of boot image
 | 
			
		||||
     
 | 
			
		||||
          mov     dx, WORD [di + 0x001A]
 | 
			
		||||
          mov     WORD [cluster], dx                  ; file's first cluster
 | 
			
		||||
          
 | 
			
		||||
     ; compute size of FAT and store in "cx"
 | 
			
		||||
     
 | 
			
		||||
          xor     ax, ax
 | 
			
		||||
          mov     al, BYTE [bpbNumberOfFATs]          ; number of FATs
 | 
			
		||||
          mul     WORD [bpbSectorsPerFAT]             ; sectors used by FATs
 | 
			
		||||
          mov     cx, ax
 | 
			
		||||
 | 
			
		||||
     ; compute location of FAT and store in "ax"
 | 
			
		||||
 | 
			
		||||
          mov     ax, WORD [bpbReservedSectors]       ; adjust for bootsector
 | 
			
		||||
          
 | 
			
		||||
     ; read FAT into memory (7C00:0200)
 | 
			
		||||
 | 
			
		||||
          mov     bx, 0x0200                          ; copy FAT above bootcode
 | 
			
		||||
          call    ReadSectors
 | 
			
		||||
 | 
			
		||||
     ; read image file into memory (0050:0000)
 | 
			
		||||
     
 | 
			
		||||
          mov     ax, 0x0050
 | 
			
		||||
          mov     es, ax                              ; destination for image
 | 
			
		||||
          mov     bx, 0x0000                          ; destination for image
 | 
			
		||||
          push    bx
 | 
			
		||||
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
     ; Load Stage 2
 | 
			
		||||
     ;----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
     LOAD_IMAGE:
 | 
			
		||||
     
 | 
			
		||||
          mov     ax, WORD [cluster]                  ; cluster to read
 | 
			
		||||
          pop     bx                                  ; buffer to read into
 | 
			
		||||
          call    ClusterLBA                          ; convert cluster to LBA
 | 
			
		||||
          xor     cx, cx
 | 
			
		||||
          mov     cl, BYTE [bpbSectorsPerCluster]     ; sectors to read
 | 
			
		||||
          call    ReadSectors
 | 
			
		||||
          push    bx
 | 
			
		||||
          
 | 
			
		||||
     ; compute next cluster
 | 
			
		||||
     
 | 
			
		||||
          mov     ax, WORD [cluster]                  ; identify current cluster
 | 
			
		||||
          mov     cx, ax                              ; copy current cluster
 | 
			
		||||
          mov     dx, ax                              ; copy current cluster
 | 
			
		||||
          shr     dx, 0x0001                          ; divide by two
 | 
			
		||||
          add     cx, dx                              ; sum for (3/2)
 | 
			
		||||
          mov     bx, 0x0200                          ; location of FAT in memory
 | 
			
		||||
          add     bx, cx                              ; index into FAT
 | 
			
		||||
          mov     dx, WORD [bx]                       ; read two bytes from FAT
 | 
			
		||||
          test    ax, 0x0001
 | 
			
		||||
          jnz     .ODD_CLUSTER
 | 
			
		||||
          
 | 
			
		||||
     .EVEN_CLUSTER:
 | 
			
		||||
     
 | 
			
		||||
          and     dx, 0000111111111111b               ; take low twelve bits
 | 
			
		||||
         jmp     .DONE
 | 
			
		||||
         
 | 
			
		||||
     .ODD_CLUSTER:
 | 
			
		||||
     
 | 
			
		||||
          shr     dx, 0x0004                          ; take high twelve bits
 | 
			
		||||
          
 | 
			
		||||
     .DONE:
 | 
			
		||||
     
 | 
			
		||||
          mov     WORD [cluster], dx                  ; store new cluster
 | 
			
		||||
          cmp     dx, 0x0FF0                          ; test for end of file
 | 
			
		||||
          jb      LOAD_IMAGE
 | 
			
		||||
          
 | 
			
		||||
     DONE:
 | 
			
		||||
          push    WORD 0x0050
 | 
			
		||||
          push    WORD 0x0000
 | 
			
		||||
          retf
 | 
			
		||||
          
 | 
			
		||||
     FAILURE:
 | 
			
		||||
     
 | 
			
		||||
          mov     si, msgFailure
 | 
			
		||||
          call    Print
 | 
			
		||||
          mov     ah, 0x00
 | 
			
		||||
          int     0x16                                ; await keypress
 | 
			
		||||
          int     0x19                                ; warm boot computer
 | 
			
		||||
     
 | 
			
		||||
     absoluteSector db 0x00
 | 
			
		||||
     absoluteHead   db 0x00
 | 
			
		||||
     absoluteTrack  db 0x00
 | 
			
		||||
     
 | 
			
		||||
     datasector  dw 0x0000
 | 
			
		||||
     cluster     dw 0x0000
 | 
			
		||||
     ImageName   db "STAGE2  CTA"
 | 
			
		||||
     msgLoading  db 0x0D, "CTA OS v0.1", 0x0A, 0x0D, "(c) CTA 2010", 0x0A, 0x0D, "Loading", 0x00
 | 
			
		||||
     msgProgress db ".", 0x00
 | 
			
		||||
     msgFailure  db 0x0D, 0x0A, "Error: Could not find stage2.bin. Press any key to reboot.", 0x0A, 0x00
 | 
			
		||||
     
 | 
			
		||||
          TIMES 510-($-$$) db 0
 | 
			
		||||
          DW 0xAA55
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								stage1/bootload.bin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								stage1/bootload.bin
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										18
									
								
								stage1/make.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								stage1/make.bat
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
@echo off
 | 
			
		||||
set nasm_path=C:\nasm
 | 
			
		||||
set djgpp_path=C:\DJGPP\bin
 | 
			
		||||
set drive=0
 | 
			
		||||
 | 
			
		||||
@echo on
 | 
			
		||||
%nasm_path%\nasm.exe -f bin bootload.asm -o bootload.bin
 | 
			
		||||
 | 
			
		||||
@echo.
 | 
			
		||||
@echo Press any key to copy to (fd%drive%), or CTRL+C to stop.
 | 
			
		||||
@pause >nul
 | 
			
		||||
 | 
			
		||||
@echo off
 | 
			
		||||
@echo w 100 %drive% 0 1 >f.tmp
 | 
			
		||||
@echo q>>f.tmp
 | 
			
		||||
 | 
			
		||||
debug bootload.bin <f.tmp
 | 
			
		||||
del f.tmp
 | 
			
		||||
							
								
								
									
										15
									
								
								stage2/MAKE.BAT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								stage2/MAKE.BAT
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
@echo off
 | 
			
		||||
set nasm_path=C:\nasm
 | 
			
		||||
set djgpp_path=C:\DJGPP\bin
 | 
			
		||||
set drive=A
 | 
			
		||||
 | 
			
		||||
@echo on
 | 
			
		||||
%nasm_path%\nasm.exe -f bin stage2.asm -o stage2.cta
 | 
			
		||||
@echo off
 | 
			
		||||
 | 
			
		||||
@echo.
 | 
			
		||||
@echo Press any key to copy to %drive%:, or CTRL+C to stop.
 | 
			
		||||
@pause >nul
 | 
			
		||||
 | 
			
		||||
@echo off
 | 
			
		||||
copy stage2.cta A:\stage2.cta
 | 
			
		||||
							
								
								
									
										103
									
								
								stage2/a20.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								stage2/a20.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
 | 
			
		||||
;********************************************
 | 
			
		||||
;	Enable A20 address line
 | 
			
		||||
;
 | 
			
		||||
;	OS Development Series
 | 
			
		||||
;********************************************
 | 
			
		||||
 | 
			
		||||
%ifndef __A20_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
%define __A20_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
 | 
			
		||||
bits	16
 | 
			
		||||
 | 
			
		||||
;----------------------------------------------
 | 
			
		||||
; Enables a20 line through keyboard controller
 | 
			
		||||
;----------------------------------------------
 | 
			
		||||
 | 
			
		||||
EnableA20_KKbrd:
 | 
			
		||||
 | 
			
		||||
	cli
 | 
			
		||||
	push	ax
 | 
			
		||||
	mov	al, 0xdd	; send enable a20 address line command to controller
 | 
			
		||||
	out	0x64, al
 | 
			
		||||
	pop	ax
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
;--------------------------------------------
 | 
			
		||||
; Enables a20 line through output port
 | 
			
		||||
;--------------------------------------------
 | 
			
		||||
 | 
			
		||||
EnableA20_KKbrd_Out:
 | 
			
		||||
 | 
			
		||||
	cli
 | 
			
		||||
	pusha
 | 
			
		||||
 | 
			
		||||
        call    wait_input
 | 
			
		||||
        mov     al,0xAD
 | 
			
		||||
        out     0x64,al		; disable keyboard
 | 
			
		||||
        call    wait_input
 | 
			
		||||
 | 
			
		||||
        mov     al,0xD0
 | 
			
		||||
        out     0x64,al		; tell controller to read output port
 | 
			
		||||
        call    wait_output
 | 
			
		||||
 | 
			
		||||
        in      al,0x60
 | 
			
		||||
        push    eax		; get output port data and store it
 | 
			
		||||
        call    wait_input
 | 
			
		||||
 | 
			
		||||
        mov     al,0xD1
 | 
			
		||||
        out     0x64,al		; tell controller to write output port
 | 
			
		||||
        call    wait_input
 | 
			
		||||
 | 
			
		||||
        pop     eax
 | 
			
		||||
        or      al,2		; set bit 1 (enable a20)
 | 
			
		||||
        out     0x60,al		; write out data back to the output port
 | 
			
		||||
 | 
			
		||||
        call    wait_input
 | 
			
		||||
        mov     al,0xAE		; enable keyboard
 | 
			
		||||
        out     0x64,al
 | 
			
		||||
 | 
			
		||||
        call    wait_input
 | 
			
		||||
	popa
 | 
			
		||||
        sti
 | 
			
		||||
        ret
 | 
			
		||||
 | 
			
		||||
	; wait for input buffer to be clear
 | 
			
		||||
 | 
			
		||||
wait_input:
 | 
			
		||||
        in      al,0x64
 | 
			
		||||
        test    al,2
 | 
			
		||||
        jnz     wait_input
 | 
			
		||||
        ret
 | 
			
		||||
 | 
			
		||||
	; wait for output buffer to be clear
 | 
			
		||||
 | 
			
		||||
wait_output:
 | 
			
		||||
        in      al,0x64
 | 
			
		||||
        test    al,1
 | 
			
		||||
        jz      wait_output
 | 
			
		||||
        ret
 | 
			
		||||
 | 
			
		||||
;--------------------------------------
 | 
			
		||||
; Enables a20 line through bios
 | 
			
		||||
;--------------------------------------
 | 
			
		||||
 | 
			
		||||
EnableA20_Bios:
 | 
			
		||||
	pusha
 | 
			
		||||
	mov	ax, 0x2401
 | 
			
		||||
	int	0x15
 | 
			
		||||
	popa
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
;-------------------------------------------------
 | 
			
		||||
; Enables a20 line through system control port A
 | 
			
		||||
;-------------------------------------------------
 | 
			
		||||
 | 
			
		||||
EnableA20_SysControlA:
 | 
			
		||||
	push	ax
 | 
			
		||||
	mov	al, 2
 | 
			
		||||
	out	0x92, al
 | 
			
		||||
	pop	ax
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
%endif
 | 
			
		||||
							
								
								
									
										17
									
								
								stage2/common.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								stage2/common.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
 | 
			
		||||
%ifndef _COMMON_INC_INCLUDED
 | 
			
		||||
%define _COMMON_INC_INCLUDED
 | 
			
		||||
 | 
			
		||||
; where the kernel is to be loaded to in protected mode
 | 
			
		||||
%define IMAGE_PMODE_BASE 0x100000
 | 
			
		||||
 | 
			
		||||
; where the kernel is to be loaded to in real mode
 | 
			
		||||
%define IMAGE_RMODE_BASE 0x3000
 | 
			
		||||
 | 
			
		||||
; kernel name (Must be 11 bytes)
 | 
			
		||||
ImageName     db "KERNEL  CTA"
 | 
			
		||||
 | 
			
		||||
; size of kernel image in bytes
 | 
			
		||||
ImageSize     db 0
 | 
			
		||||
 | 
			
		||||
%endif
 | 
			
		||||
							
								
								
									
										243
									
								
								stage2/fat12.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								stage2/fat12.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,243 @@
 | 
			
		||||
 | 
			
		||||
;*******************************************************
 | 
			
		||||
;
 | 
			
		||||
;	Fat12.inc
 | 
			
		||||
;		FAT12 filesystem for 3-1/2 floppies
 | 
			
		||||
;
 | 
			
		||||
;	OS Development Series
 | 
			
		||||
;*******************************************************
 | 
			
		||||
 | 
			
		||||
%ifndef __FAT12_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
%define __FAT12_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
 | 
			
		||||
bits	16
 | 
			
		||||
 | 
			
		||||
%include "Floppy16.inc"					; the erm.. floppy driver
 | 
			
		||||
 | 
			
		||||
%define ROOT_OFFSET 0x2e00
 | 
			
		||||
%define FAT_SEG 0x2c0
 | 
			
		||||
%define ROOT_SEG 0x2e0
 | 
			
		||||
 | 
			
		||||
;*******************************************
 | 
			
		||||
; LoadRoot ()
 | 
			
		||||
;	- Load Root Directory Table to 0x7e00
 | 
			
		||||
;*******************************************
 | 
			
		||||
 | 
			
		||||
LoadRoot:
 | 
			
		||||
 | 
			
		||||
	pusha							; store registers
 | 
			
		||||
	push	es
 | 
			
		||||
 | 
			
		||||
     ; compute size of root directory and store in "cx"
 | 
			
		||||
     
 | 
			
		||||
	xor     cx, cx						; clear registers
 | 
			
		||||
 	xor     dx, dx
 | 
			
		||||
	mov     ax, 32					; 32 byte directory entry
 | 
			
		||||
	mul     WORD [bpbRootEntries]				; total size of directory
 | 
			
		||||
	div     WORD [bpbBytesPerSector]			; sectors used by directory
 | 
			
		||||
	xchg    ax, cx						; move into AX
 | 
			
		||||
 | 
			
		||||
     ; compute location of root directory and store in "ax"
 | 
			
		||||
     
 | 
			
		||||
	mov     al, BYTE [bpbNumberOfFATs]			; number of FATs
 | 
			
		||||
	mul     WORD [bpbSectorsPerFAT]				; sectors used by FATs
 | 
			
		||||
	add     ax, WORD [bpbReservedSectors]
 | 
			
		||||
	mov     WORD [datasector], ax				; base of root directory
 | 
			
		||||
	add     WORD [datasector], cx
 | 
			
		||||
 | 
			
		||||
     ; read root directory into 0x7e00
 | 
			
		||||
 
 | 
			
		||||
 	push	word ROOT_SEG
 | 
			
		||||
	pop		es
 | 
			
		||||
	mov     bx, 0								; copy root dir
 | 
			
		||||
	call    ReadSectors							; read in directory table
 | 
			
		||||
	pop		es
 | 
			
		||||
	popa										; restore registers and return
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
;*******************************************
 | 
			
		||||
; LoadFAT ()
 | 
			
		||||
;	- Loads FAT table to 0x7c00
 | 
			
		||||
;
 | 
			
		||||
;	Parm/ ES:DI => Root Directory Table
 | 
			
		||||
;*******************************************
 | 
			
		||||
 | 
			
		||||
LoadFAT:
 | 
			
		||||
 | 
			
		||||
	pusha							; store registers
 | 
			
		||||
	push	es
 | 
			
		||||
 | 
			
		||||
     ; compute size of FAT and store in "cx"
 | 
			
		||||
     
 | 
			
		||||
	xor     ax, ax
 | 
			
		||||
	mov     al, BYTE [bpbNumberOfFATs]			; number of FATs
 | 
			
		||||
	mul     WORD [bpbSectorsPerFAT]				; sectors used by FATs
 | 
			
		||||
	mov     cx, ax
 | 
			
		||||
 | 
			
		||||
     ; compute location of FAT and store in "ax"
 | 
			
		||||
 | 
			
		||||
	mov     ax, WORD [bpbReservedSectors]
 | 
			
		||||
 | 
			
		||||
     ; read FAT into memory (Overwrite our bootloader at 0x7c00)
 | 
			
		||||
 | 
			
		||||
	push	word FAT_SEG
 | 
			
		||||
	pop		es
 | 
			
		||||
	xor		bx, bx
 | 
			
		||||
	call    ReadSectors
 | 
			
		||||
	pop		es
 | 
			
		||||
	popa							; restore registers and return
 | 
			
		||||
	ret
 | 
			
		||||
	
 | 
			
		||||
;*******************************************
 | 
			
		||||
; FindFile ()
 | 
			
		||||
;	- Search for filename in root table
 | 
			
		||||
;
 | 
			
		||||
; parm/ DS:SI => File name
 | 
			
		||||
; ret/ AX => File index number in directory table. -1 if error
 | 
			
		||||
;*******************************************
 | 
			
		||||
 | 
			
		||||
FindFile:
 | 
			
		||||
 | 
			
		||||
	push	cx						; store registers
 | 
			
		||||
	push	dx
 | 
			
		||||
	push	bx
 | 
			
		||||
	mov	bx, si						; copy filename for later
 | 
			
		||||
 | 
			
		||||
     ; browse root directory for binary image
 | 
			
		||||
 | 
			
		||||
	mov     cx, WORD [bpbRootEntries]			; load loop counter
 | 
			
		||||
	mov     di, ROOT_OFFSET						; locate first root entry at 1 MB mark
 | 
			
		||||
	cld							; clear direction flag
 | 
			
		||||
 | 
			
		||||
.LOOP:
 | 
			
		||||
	push    cx
 | 
			
		||||
	mov     cx, 11					; eleven character name. Image name is in SI
 | 
			
		||||
	mov	si, bx						; image name is in BX
 | 
			
		||||
 	push    di
 | 
			
		||||
     rep  cmpsb							; test for entry match
 | 
			
		||||
	pop     di
 | 
			
		||||
	je      .Found
 | 
			
		||||
	pop     cx
 | 
			
		||||
	add     di, 32					; queue next directory entry
 | 
			
		||||
	loop    .LOOP
 | 
			
		||||
 | 
			
		||||
.NotFound:
 | 
			
		||||
	pop	bx						; restore registers and return
 | 
			
		||||
	pop	dx
 | 
			
		||||
	pop	cx
 | 
			
		||||
	mov	ax, -1						; set error code
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.Found:
 | 
			
		||||
	pop	ax						; return value into AX contains entry of file
 | 
			
		||||
	pop	bx						; restore registers and return
 | 
			
		||||
	pop	dx
 | 
			
		||||
	pop	cx
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
;*******************************************
 | 
			
		||||
; LoadFile ()
 | 
			
		||||
;	- Load file
 | 
			
		||||
; parm/ ES:SI => File to load
 | 
			
		||||
; parm/ EBX:BP => Buffer to load file to
 | 
			
		||||
; ret/ AX => -1 on error, 0 on success
 | 
			
		||||
; ret/ CX => number of sectors read
 | 
			
		||||
;*******************************************
 | 
			
		||||
 | 
			
		||||
LoadFile:
 | 
			
		||||
 | 
			
		||||
	xor	ecx, ecx		; size of file in sectors
 | 
			
		||||
	push	ecx
 | 
			
		||||
 | 
			
		||||
.FIND_FILE:
 | 
			
		||||
 | 
			
		||||
	push	bx			; BX=>BP points to buffer to write to; store it for later
 | 
			
		||||
	push	bp
 | 
			
		||||
	call	FindFile		; find our file. ES:SI contains our filename
 | 
			
		||||
	cmp	ax, -1
 | 
			
		||||
	jne	.LOAD_IMAGE_PRE
 | 
			
		||||
	pop	bp
 | 
			
		||||
	pop	bx
 | 
			
		||||
	pop	ecx
 | 
			
		||||
	mov	ax, -1
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.LOAD_IMAGE_PRE:
 | 
			
		||||
 | 
			
		||||
	sub	edi, ROOT_OFFSET
 | 
			
		||||
	sub	eax, ROOT_OFFSET
 | 
			
		||||
 | 
			
		||||
	; get starting cluster
 | 
			
		||||
 | 
			
		||||
	push	word ROOT_SEG		;root segment loc
 | 
			
		||||
	pop	es
 | 
			
		||||
	mov	dx, WORD [es:di + 0x001A]; DI points to file entry in root directory table. Refrence the table...
 | 
			
		||||
	mov	WORD [cluster], dx	; file's first cluster
 | 
			
		||||
	pop	bx			; get location to write to so we dont screw up the stack
 | 
			
		||||
	pop	es
 | 
			
		||||
	push    bx			; store location for later again
 | 
			
		||||
	push	es
 | 
			
		||||
	call	LoadFAT
 | 
			
		||||
 | 
			
		||||
.LOAD_IMAGE:
 | 
			
		||||
 | 
			
		||||
	; load the cluster
 | 
			
		||||
 | 
			
		||||
	mov	ax, WORD [cluster]	; cluster to read
 | 
			
		||||
	pop	es			; bx:bp=es:bx
 | 
			
		||||
	pop	bx
 | 
			
		||||
	call	ClusterLBA
 | 
			
		||||
	xor	cx, cx
 | 
			
		||||
	mov     cl, BYTE [bpbSectorsPerCluster]
 | 
			
		||||
	call	ReadSectors
 | 
			
		||||
	pop	ecx
 | 
			
		||||
	inc	ecx			; add one more sector to counter
 | 
			
		||||
	push	ecx
 | 
			
		||||
	push	bx
 | 
			
		||||
	push	es
 | 
			
		||||
	mov	ax, FAT_SEG		;start reading from fat
 | 
			
		||||
	mov	es, ax
 | 
			
		||||
	xor	bx, bx
 | 
			
		||||
 | 
			
		||||
	; get next cluster
 | 
			
		||||
 | 
			
		||||
	mov     ax, WORD [cluster]	; identify current cluster
 | 
			
		||||
	mov     cx, ax			; copy current cluster
 | 
			
		||||
	mov     dx, ax
 | 
			
		||||
	shr     dx, 0x0001		; divide by two
 | 
			
		||||
	add     cx, dx			; sum for (3/2)
 | 
			
		||||
 | 
			
		||||
	mov	bx, 0			;location of fat in memory
 | 
			
		||||
	add	bx, cx
 | 
			
		||||
	mov	dx, WORD [es:bx]
 | 
			
		||||
	test	ax, 0x0001		; test for odd or even cluster
 | 
			
		||||
	jnz	.ODD_CLUSTER
 | 
			
		||||
 | 
			
		||||
.EVEN_CLUSTER:
 | 
			
		||||
 | 
			
		||||
	and	dx, 0000111111111111b	; take low 12 bits
 | 
			
		||||
	jmp	.DONE
 | 
			
		||||
 | 
			
		||||
.ODD_CLUSTER:
 | 
			
		||||
 | 
			
		||||
	shr	dx, 0x0004		; take high 12 bits
 | 
			
		||||
 | 
			
		||||
.DONE:
 | 
			
		||||
 | 
			
		||||
	mov	WORD [cluster], dx
 | 
			
		||||
	cmp	dx, 0x0ff0		; test for end of file marker
 | 
			
		||||
	jb	.LOAD_IMAGE
 | 
			
		||||
 | 
			
		||||
.SUCCESS:
 | 
			
		||||
	pop	es
 | 
			
		||||
	pop	bx
 | 
			
		||||
	pop	ecx
 | 
			
		||||
	xor	ax, ax
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
%endif		;__FAT12_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										117
									
								
								stage2/floppy16.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								stage2/floppy16.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
 | 
			
		||||
;*******************************************************
 | 
			
		||||
;
 | 
			
		||||
;	Floppy16.inc
 | 
			
		||||
;		Floppy drive interface routines
 | 
			
		||||
;
 | 
			
		||||
;	OS Development Series
 | 
			
		||||
;*******************************************************
 | 
			
		||||
 | 
			
		||||
%ifndef __FLOPPY16_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
%define __FLOPPY16_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
 | 
			
		||||
bits	16
 | 
			
		||||
 | 
			
		||||
bpbOEM			db "My OS   "
 | 
			
		||||
bpbBytesPerSector:  	DW 512
 | 
			
		||||
bpbSectorsPerCluster: 	DB 1
 | 
			
		||||
bpbReservedSectors: 	DW 1
 | 
			
		||||
bpbNumberOfFATs: 	DB 2
 | 
			
		||||
bpbRootEntries: 	DW 224
 | 
			
		||||
bpbTotalSectors: 	DW 2880
 | 
			
		||||
bpbMedia: 		DB 0xf0  ;; 0xF1
 | 
			
		||||
bpbSectorsPerFAT: 	DW 9
 | 
			
		||||
bpbSectorsPerTrack: 	DW 18
 | 
			
		||||
bpbHeadsPerCylinder: 	DW 2
 | 
			
		||||
bpbHiddenSectors: 	DD 0
 | 
			
		||||
bpbTotalSectorsBig:     DD 0
 | 
			
		||||
bsDriveNumber: 	        DB 0
 | 
			
		||||
bsUnused: 		DB 0
 | 
			
		||||
bsExtBootSignature: 	DB 0x29
 | 
			
		||||
bsSerialNumber:	        DD 0xa0a1a2a3
 | 
			
		||||
bsVolumeLabel: 	        DB "MOS FLOPPY "
 | 
			
		||||
bsFileSystem: 	        DB "FAT12   "
 | 
			
		||||
 | 
			
		||||
datasector  dw 0x0000
 | 
			
		||||
cluster     dw 0x0000
 | 
			
		||||
 | 
			
		||||
absoluteSector db 0x00
 | 
			
		||||
absoluteHead   db 0x00
 | 
			
		||||
absoluteTrack  db 0x00
 | 
			
		||||
 | 
			
		||||
;************************************************;
 | 
			
		||||
; Convert CHS to LBA
 | 
			
		||||
; LBA = (cluster - 2) * sectors per cluster
 | 
			
		||||
;************************************************;
 | 
			
		||||
 | 
			
		||||
ClusterLBA:
 | 
			
		||||
          sub     ax, 0x0002                          ; zero base cluster number
 | 
			
		||||
          xor     cx, cx
 | 
			
		||||
          mov     cl, BYTE [bpbSectorsPerCluster]     ; convert byte to word
 | 
			
		||||
          mul     cx
 | 
			
		||||
          add     ax, WORD [datasector]               ; base data sector
 | 
			
		||||
          ret
 | 
			
		||||
 | 
			
		||||
;************************************************;
 | 
			
		||||
; Convert LBA to CHS
 | 
			
		||||
; AX=>LBA Address to convert
 | 
			
		||||
;
 | 
			
		||||
; absolute sector = (logical sector / sectors per track) + 1
 | 
			
		||||
; absolute head   = (logical sector / sectors per track) MOD number of heads
 | 
			
		||||
; absolute track  = logical sector / (sectors per track * number of heads)
 | 
			
		||||
;
 | 
			
		||||
;************************************************;
 | 
			
		||||
 | 
			
		||||
LBACHS:
 | 
			
		||||
          xor     dx, dx                              ; prepare dx:ax for operation
 | 
			
		||||
          div     WORD [bpbSectorsPerTrack]           ; calculate
 | 
			
		||||
          inc     dl                                  ; adjust for sector 0
 | 
			
		||||
          mov     BYTE [absoluteSector], dl
 | 
			
		||||
          xor     dx, dx                              ; prepare dx:ax for operation
 | 
			
		||||
          div     WORD [bpbHeadsPerCylinder]          ; calculate
 | 
			
		||||
          mov     BYTE [absoluteHead], dl
 | 
			
		||||
          mov     BYTE [absoluteTrack], al
 | 
			
		||||
          ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;************************************************;
 | 
			
		||||
; Reads a series of sectors
 | 
			
		||||
; CX=>Number of sectors to read
 | 
			
		||||
; AX=>Starting sector
 | 
			
		||||
; ES:EBX=>Buffer to read to
 | 
			
		||||
;************************************************;
 | 
			
		||||
 | 
			
		||||
ReadSectors:
 | 
			
		||||
     .MAIN:
 | 
			
		||||
          mov     di, 0x0005                          ; five retries for error
 | 
			
		||||
     .SECTORLOOP:
 | 
			
		||||
          push    ax
 | 
			
		||||
          push    bx
 | 
			
		||||
          push    cx
 | 
			
		||||
          call    LBACHS                              ; convert starting sector to CHS
 | 
			
		||||
          mov     ah, 0x02                            ; BIOS read sector
 | 
			
		||||
          mov     al, 0x01                            ; read one sector
 | 
			
		||||
          mov     ch, BYTE [absoluteTrack]            ; track
 | 
			
		||||
          mov     cl, BYTE [absoluteSector]           ; sector
 | 
			
		||||
          mov     dh, BYTE [absoluteHead]             ; head
 | 
			
		||||
          mov     dl, BYTE [bsDriveNumber]            ; drive
 | 
			
		||||
          int     0x13                                ; invoke BIOS
 | 
			
		||||
          jnc     .SUCCESS                            ; test for read error
 | 
			
		||||
          xor     ax, ax                              ; BIOS reset disk
 | 
			
		||||
          int     0x13                                ; invoke BIOS
 | 
			
		||||
          dec     di                                  ; decrement error counter
 | 
			
		||||
          pop     cx
 | 
			
		||||
          pop     bx
 | 
			
		||||
          pop     ax
 | 
			
		||||
          jnz     .SECTORLOOP                         ; attempt to read again
 | 
			
		||||
          int     0x18
 | 
			
		||||
     .SUCCESS:
 | 
			
		||||
          pop     cx
 | 
			
		||||
          pop     bx
 | 
			
		||||
          pop     ax
 | 
			
		||||
          add     bx, WORD [bpbBytesPerSector]        ; queue next buffer
 | 
			
		||||
          inc     ax                                  ; queue next sector
 | 
			
		||||
          loop    .MAIN                               ; read next sector
 | 
			
		||||
          ret
 | 
			
		||||
 | 
			
		||||
%endif		;__FLOPPY16_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
							
								
								
									
										68
									
								
								stage2/gdt.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								stage2/gdt.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;*************************************************
 | 
			
		||||
;	Gdt.inc
 | 
			
		||||
;		-GDT Routines
 | 
			
		||||
;
 | 
			
		||||
;	OS Development Series
 | 
			
		||||
;*************************************************
 | 
			
		||||
 | 
			
		||||
%ifndef __GDT_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
%define __GDT_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
 | 
			
		||||
bits	16
 | 
			
		||||
 | 
			
		||||
;*******************************************
 | 
			
		||||
; InstallGDT()
 | 
			
		||||
;	- Install our GDT
 | 
			
		||||
;*******************************************
 | 
			
		||||
 | 
			
		||||
InstallGDT:
 | 
			
		||||
 | 
			
		||||
	cli                  ; clear interrupts
 | 
			
		||||
	pusha                ; save registers
 | 
			
		||||
	lgdt 	[toc]        ; load GDT into GDTR
 | 
			
		||||
	sti	                 ; enable interrupts
 | 
			
		||||
	popa                 ; restore registers
 | 
			
		||||
	ret	                 ; All done!
 | 
			
		||||
 | 
			
		||||
;*******************************************
 | 
			
		||||
; Global Descriptor Table (GDT)
 | 
			
		||||
;*******************************************
 | 
			
		||||
 | 
			
		||||
gdt_data: 
 | 
			
		||||
	dd 0                ; null descriptor
 | 
			
		||||
	dd 0 
 | 
			
		||||
 | 
			
		||||
; gdt code:	            ; code descriptor
 | 
			
		||||
	dw 0FFFFh           ; limit low
 | 
			
		||||
	dw 0                ; base low
 | 
			
		||||
	db 0                ; base middle
 | 
			
		||||
	db 10011010b        ; access
 | 
			
		||||
	db 11001111b        ; granularity
 | 
			
		||||
	db 0                ; base high
 | 
			
		||||
 | 
			
		||||
; gdt data:	            ; data descriptor
 | 
			
		||||
	dw 0FFFFh           ; limit low (Same as code)10:56 AM 7/8/2007
 | 
			
		||||
	dw 0                ; base low
 | 
			
		||||
	db 0                ; base middle
 | 
			
		||||
	db 10010010b        ; access
 | 
			
		||||
	db 11001111b        ; granularity
 | 
			
		||||
	db 0                ; base high
 | 
			
		||||
	
 | 
			
		||||
end_of_gdt:
 | 
			
		||||
toc: 
 | 
			
		||||
	dw end_of_gdt - gdt_data - 1 	; limit (Size of GDT)
 | 
			
		||||
	dd gdt_data 			; base of GDT
 | 
			
		||||
 | 
			
		||||
; give the descriptor offsets names
 | 
			
		||||
 | 
			
		||||
%define NULL_DESC 0
 | 
			
		||||
%define CODE_DESC 0x8
 | 
			
		||||
%define DATA_DESC 0x10
 | 
			
		||||
 | 
			
		||||
%endif ;__GDT_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										158
									
								
								stage2/stage2.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								stage2/stage2.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
 | 
			
		||||
;*******************************************************
 | 
			
		||||
;
 | 
			
		||||
;	Stage2.asm
 | 
			
		||||
;		Stage2 Bootloader
 | 
			
		||||
;
 | 
			
		||||
;	OS Development Series
 | 
			
		||||
;*******************************************************
 | 
			
		||||
 | 
			
		||||
bits	16
 | 
			
		||||
 | 
			
		||||
; Remember the memory map-- 0x500 through 0x7bff is unused above the BIOS data area.
 | 
			
		||||
; We are loaded at 0x500 (0x50:0)
 | 
			
		||||
 | 
			
		||||
org 0x500
 | 
			
		||||
 | 
			
		||||
jmp	main				; go to start
 | 
			
		||||
 | 
			
		||||
;*******************************************************
 | 
			
		||||
;	Preprocessor directives
 | 
			
		||||
;*******************************************************
 | 
			
		||||
 | 
			
		||||
%include "stdio.inc"			; basic i/o routines
 | 
			
		||||
%include "Gdt.inc"			; Gdt routines
 | 
			
		||||
%include "A20.inc"			; A20 enabling
 | 
			
		||||
%include "Fat12.inc"			; FAT12 driver. Kinda :)
 | 
			
		||||
%include "common.inc"
 | 
			
		||||
 | 
			
		||||
;*******************************************************
 | 
			
		||||
;	Data Section
 | 
			
		||||
;*******************************************************
 | 
			
		||||
 | 
			
		||||
msgFailure db 0x0A, 0x0D, "FATAL ERROR: MISSING OR CORRUPT KERNEL.CTA", 0x0A, 0x0D, "Press any key to reboot...", 0x0D, 0x0A, 0x00
 | 
			
		||||
 | 
			
		||||
;*******************************************************
 | 
			
		||||
;	STAGE 2 ENTRY POINT
 | 
			
		||||
;
 | 
			
		||||
;		-Store BIOS information
 | 
			
		||||
;		-Load Kernel
 | 
			
		||||
;		-Install GDT; go into protected mode (pmode)
 | 
			
		||||
;		-Jump to Stage 3
 | 
			
		||||
;*******************************************************
 | 
			
		||||
 | 
			
		||||
main:
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Setup segments and stack	;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	cli				; clear interrupts
 | 
			
		||||
	xor	ax, ax			; null segments
 | 
			
		||||
	mov	ds, ax
 | 
			
		||||
	mov	es, ax
 | 
			
		||||
	mov	ax, 0x0			; stack begins at 0x9000-0xffff
 | 
			
		||||
	mov	ss, ax
 | 
			
		||||
	mov	sp, 0xFFFF
 | 
			
		||||
	sti				; enable interrupts
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Install our GDT		;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	call	InstallGDT		; install our GDT
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Enable A20			;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	call	EnableA20_KKbrd_Out
 | 
			
		||||
 | 
			
		||||
        ;-------------------------------;
 | 
			
		||||
        ; Initialize filesystem		;
 | 
			
		||||
        ;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	call	LoadRoot		; Load root directory table
 | 
			
		||||
 | 
			
		||||
        ;-------------------------------;
 | 
			
		||||
        ; Load Kernel			;
 | 
			
		||||
        ;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	mov	ebx, 0			; BX:BP points to buffer to load to
 | 
			
		||||
    	mov	bp, IMAGE_RMODE_BASE
 | 
			
		||||
	mov	si, ImageName		; our file to load
 | 
			
		||||
	call	LoadFile		; load our file
 | 
			
		||||
	mov	dword [ImageSize], ecx	; save size of kernel
 | 
			
		||||
	cmp	ax, 0			; Test for success
 | 
			
		||||
	je	EnterStage3		; yep--onto Stage 3!
 | 
			
		||||
	mov	si, msgFailure		; Nope--print error
 | 
			
		||||
	call	Puts16
 | 
			
		||||
	mov	ah, 0
 | 
			
		||||
	int     0x16                    ; await keypress
 | 
			
		||||
	int     0x19                    ; warm boot computer
 | 
			
		||||
	cli				; If we get here, something really went wong
 | 
			
		||||
	hlt
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Go into pmode		;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
EnterStage3:
 | 
			
		||||
 | 
			
		||||
	cli				; clear interrupts
 | 
			
		||||
	mov	eax, cr0		; set bit 0 in cr0--enter pmode
 | 
			
		||||
	or	eax, 1
 | 
			
		||||
	mov	cr0, eax
 | 
			
		||||
 | 
			
		||||
	jmp	CODE_DESC:Stage3	; far jump to fix CS. Remember that the code selector is 0x8!
 | 
			
		||||
 | 
			
		||||
	; Note: Do NOT re-enable interrupts! Doing so will triple fault!
 | 
			
		||||
	; We will fix this in Stage 3.
 | 
			
		||||
 | 
			
		||||
;******************************************************
 | 
			
		||||
;	ENTRY POINT FOR STAGE 3
 | 
			
		||||
;******************************************************
 | 
			
		||||
 | 
			
		||||
bits 32
 | 
			
		||||
 | 
			
		||||
Stage3:
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Set registers		;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	mov	ax, DATA_DESC	; set data segments to data selector (0x10)
 | 
			
		||||
	mov	ds, ax
 | 
			
		||||
	mov	ss, ax
 | 
			
		||||
	mov	es, ax
 | 
			
		||||
	mov	esp, 90000h		; stack begins from 90000h
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	; Copy kernel to 1MB		;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
CopyImage:
 | 
			
		||||
  	 mov	eax, dword [ImageSize]
 | 
			
		||||
  	 movzx	ebx, word [bpbBytesPerSector]
 | 
			
		||||
  	 mul	ebx
 | 
			
		||||
  	 mov	ebx, 4
 | 
			
		||||
  	 div	ebx
 | 
			
		||||
   	 cld
 | 
			
		||||
   	 mov    esi, IMAGE_RMODE_BASE
 | 
			
		||||
   	 mov	edi, IMAGE_PMODE_BASE
 | 
			
		||||
   	 mov	ecx, eax
 | 
			
		||||
   	 rep	movsd                   ; copy image to its protected mode address
 | 
			
		||||
 | 
			
		||||
	;---------------------------------------;
 | 
			
		||||
	;   Execute Kernel			;
 | 
			
		||||
	;---------------------------------------;
 | 
			
		||||
 | 
			
		||||
	jmp	CODE_DESC:IMAGE_PMODE_BASE; jump to our kernel! Note: This assumes Kernel's entry point is at 1 MB
 | 
			
		||||
 | 
			
		||||
	;---------------------------------------;
 | 
			
		||||
	;   Stop execution			;
 | 
			
		||||
	;---------------------------------------;
 | 
			
		||||
 | 
			
		||||
	cli
 | 
			
		||||
	hlt
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								stage2/stage2.cta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								stage2/stage2.cta
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										298
									
								
								stage2/stdio.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								stage2/stdio.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,298 @@
 | 
			
		||||
 | 
			
		||||
;*************************************************
 | 
			
		||||
;	stdio.inc
 | 
			
		||||
;		-Input/Output routines
 | 
			
		||||
;
 | 
			
		||||
;	OS Development Series
 | 
			
		||||
;*************************************************
 | 
			
		||||
 | 
			
		||||
%ifndef __STDIO_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
%define __STDIO_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;==========================================================
 | 
			
		||||
;
 | 
			
		||||
;	 16 Bit Real Mode Routines
 | 
			
		||||
;==========================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;************************************************;
 | 
			
		||||
;	Puts16 ()
 | 
			
		||||
;		-Prints a null terminated string
 | 
			
		||||
;	DS=>SI: 0 terminated string
 | 
			
		||||
;************************************************;
 | 
			
		||||
 | 
			
		||||
bits	16
 | 
			
		||||
 | 
			
		||||
Puts16:
 | 
			
		||||
		pusha				; save registers
 | 
			
		||||
.Loop1:
 | 
			
		||||
		lodsb				; load next byte from string from SI to AL
 | 
			
		||||
		or	al, al			; Does AL=0?
 | 
			
		||||
		jz	Puts16Done		; Yep, null terminator found-bail out
 | 
			
		||||
		mov	ah, 0eh			; Nope-Print the character
 | 
			
		||||
		int	10h			; invoke BIOS
 | 
			
		||||
		jmp	.Loop1			; Repeat until null terminator found
 | 
			
		||||
Puts16Done:
 | 
			
		||||
		popa				; restore registers
 | 
			
		||||
		ret				; we are done, so return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;==========================================================
 | 
			
		||||
;
 | 
			
		||||
;	 32 Bit Protected Mode Routines
 | 
			
		||||
;==========================================================
 | 
			
		||||
 | 
			
		||||
bits 32
 | 
			
		||||
 | 
			
		||||
%define		VIDMEM	0xB8000			; video memory
 | 
			
		||||
%define		COLS	80			; width and height of screen
 | 
			
		||||
%define		LINES	25
 | 
			
		||||
%define		CHAR_ATTRIB 63			; character attribute (White text on light blue background)
 | 
			
		||||
 | 
			
		||||
_CurX db 0					; current x/y location
 | 
			
		||||
_CurY db 0
 | 
			
		||||
 | 
			
		||||
;**************************************************;
 | 
			
		||||
;	Putch32 ()
 | 
			
		||||
;		- Prints a character to screen
 | 
			
		||||
;	BL => Character to print
 | 
			
		||||
;**************************************************;
 | 
			
		||||
 | 
			
		||||
Putch32:
 | 
			
		||||
 | 
			
		||||
	pusha				; save registers
 | 
			
		||||
	mov	edi, VIDMEM		; get pointer to video memory
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Get current position	;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	xor	eax, eax		; clear eax
 | 
			
		||||
 | 
			
		||||
		;--------------------------------
 | 
			
		||||
		; Remember: currentPos = x + y * COLS! x and y are in _CurX and _CurY.
 | 
			
		||||
		; Because there are two bytes per character, COLS=number of characters in a line.
 | 
			
		||||
		; We have to multiply this by 2 to get number of bytes per line. This is the screen width,
 | 
			
		||||
		; so multiply screen with * _CurY to get current line
 | 
			
		||||
		;--------------------------------
 | 
			
		||||
 | 
			
		||||
		mov	ecx, COLS*2		; Mode 7 has 2 bytes per char, so its COLS*2 bytes per line
 | 
			
		||||
		mov	al, byte [_CurY]	; get y pos
 | 
			
		||||
		mul	ecx			; multiply y*COLS
 | 
			
		||||
		push	eax			; save eax--the multiplication
 | 
			
		||||
 | 
			
		||||
		;--------------------------------
 | 
			
		||||
		; Now y * screen width is in eax. Now, just add _CurX. But, again remember that _CurX is relative
 | 
			
		||||
		; to the current character count, not byte count. Because there are two bytes per character, we
 | 
			
		||||
		; have to multiply _CurX by 2 first, then add it to our screen width * y.
 | 
			
		||||
		;--------------------------------
 | 
			
		||||
 | 
			
		||||
		mov	al, byte [_CurX]	; multiply _CurX by 2 because it is 2 bytes per char
 | 
			
		||||
		mov	cl, 2
 | 
			
		||||
		mul	cl
 | 
			
		||||
		pop	ecx			; pop y*COLS result
 | 
			
		||||
		add	eax, ecx
 | 
			
		||||
 | 
			
		||||
		;-------------------------------
 | 
			
		||||
		; Now eax contains the offset address to draw the character at, so just add it to the base address
 | 
			
		||||
		; of video memory (Stored in edi)
 | 
			
		||||
		;-------------------------------
 | 
			
		||||
 | 
			
		||||
		xor	ecx, ecx
 | 
			
		||||
		add	edi, eax		; add it to the base address
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Watch for new line          ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	cmp	bl, 0x0A		; is it a newline character?
 | 
			
		||||
	je	.Row			; yep--go to next row
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Print a character           ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	mov	dl, bl			; Get character
 | 
			
		||||
	mov	dh, CHAR_ATTRIB		; the character attribute
 | 
			
		||||
	mov	word [edi], dx		; write to video display
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Update next position        ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	inc	byte [_CurX]		; go to next character
 | 
			
		||||
;	cmp	byte [_CurX], COLS		; are we at the end of the line?
 | 
			
		||||
;	je	.Row			; yep-go to next row
 | 
			
		||||
	jmp	.done			; nope, bail out
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Go to next row              ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
.Row:
 | 
			
		||||
	mov	byte [_CurX], 0		; go back to col 0
 | 
			
		||||
	inc	byte [_CurY]		; go to next row
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Restore registers & return  ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
.done:
 | 
			
		||||
	popa				; restore registers and return
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
;**************************************************;
 | 
			
		||||
;	Puts32 ()
 | 
			
		||||
;		- Prints a null terminated string
 | 
			
		||||
;	parm\ EBX = address of string to print
 | 
			
		||||
;**************************************************;
 | 
			
		||||
 | 
			
		||||
Puts32:
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Store registers             ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	pusha				; save registers
 | 
			
		||||
	push	ebx			; copy the string address
 | 
			
		||||
	pop	edi
 | 
			
		||||
 | 
			
		||||
.loop:
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Get character               ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	mov	bl, byte [edi]		; get next character
 | 
			
		||||
	cmp	bl, 0			; is it 0 (Null terminator)?
 | 
			
		||||
	je	.done			; yep-bail out
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Print the character         ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	call	Putch32			; Nope-print it out
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Go to next character        ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	inc	edi			; go to next character
 | 
			
		||||
	jmp	.loop
 | 
			
		||||
 | 
			
		||||
.done:
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Update hardware cursor      ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	; Its more efficiant to update the cursor after displaying
 | 
			
		||||
	; the complete string because direct VGA is slow
 | 
			
		||||
 | 
			
		||||
	mov	bh, byte [_CurY]	; get current position
 | 
			
		||||
	mov	bl, byte [_CurX]
 | 
			
		||||
	call	MovCur			; update cursor
 | 
			
		||||
 | 
			
		||||
	popa				; restore registers, and return
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
;**************************************************;
 | 
			
		||||
;	MoveCur ()
 | 
			
		||||
;		- Update hardware cursor
 | 
			
		||||
;	parm/ bh = Y pos
 | 
			
		||||
;	parm/ bl = x pos
 | 
			
		||||
;**************************************************;
 | 
			
		||||
 | 
			
		||||
bits 32
 | 
			
		||||
 | 
			
		||||
MovCur:
 | 
			
		||||
 | 
			
		||||
	pusha				; save registers (aren't you getting tired of this comment?)
 | 
			
		||||
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
	;   Get current position        ;
 | 
			
		||||
	;-------------------------------;
 | 
			
		||||
 | 
			
		||||
	; Here, _CurX and _CurY are relitave to the current position on screen, not in memory.
 | 
			
		||||
	; That is, we don't need to worry about the byte alignment we do when displaying characters,
 | 
			
		||||
	; so just follow the forumla: location = _CurX + _CurY * COLS
 | 
			
		||||
 | 
			
		||||
	xor	eax, eax
 | 
			
		||||
	mov	ecx, COLS
 | 
			
		||||
	mov	al, bh			; get y pos
 | 
			
		||||
	mul	ecx			; multiply y*COLS
 | 
			
		||||
	add	al, bl			; Now add x
 | 
			
		||||
	mov	ebx, eax
 | 
			
		||||
 | 
			
		||||
	;--------------------------------------;
 | 
			
		||||
	;   Set low byte index to VGA register ;
 | 
			
		||||
	;--------------------------------------;
 | 
			
		||||
 | 
			
		||||
	mov	al, 0x0f
 | 
			
		||||
	mov	dx, 0x03D4
 | 
			
		||||
	out	dx, al
 | 
			
		||||
 | 
			
		||||
	mov	al, bl
 | 
			
		||||
	mov	dx, 0x03D5
 | 
			
		||||
	out	dx, al			; low byte
 | 
			
		||||
 | 
			
		||||
	;---------------------------------------;
 | 
			
		||||
	;   Set high byte index to VGA register ;
 | 
			
		||||
	;---------------------------------------;
 | 
			
		||||
 | 
			
		||||
	xor	eax, eax
 | 
			
		||||
 | 
			
		||||
	mov	al, 0x0e
 | 
			
		||||
	mov	dx, 0x03D4
 | 
			
		||||
	out	dx, al
 | 
			
		||||
 | 
			
		||||
	mov	al, bh
 | 
			
		||||
	mov	dx, 0x03D5
 | 
			
		||||
	out	dx, al			; high byte
 | 
			
		||||
 | 
			
		||||
	popa
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
;**************************************************;
 | 
			
		||||
;	ClrScr32 ()
 | 
			
		||||
;		- Clears screen
 | 
			
		||||
;**************************************************;
 | 
			
		||||
 | 
			
		||||
bits 32
 | 
			
		||||
 | 
			
		||||
ClrScr32:
 | 
			
		||||
 | 
			
		||||
	pusha
 | 
			
		||||
	cld
 | 
			
		||||
	mov	edi, VIDMEM
 | 
			
		||||
	mov	cx, 2000
 | 
			
		||||
	mov	ah, CHAR_ATTRIB
 | 
			
		||||
	mov	al, ' '	
 | 
			
		||||
	rep	stosw
 | 
			
		||||
 | 
			
		||||
	mov	byte [_CurX], 0
 | 
			
		||||
	mov	byte [_CurY], 0
 | 
			
		||||
	popa
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
;**************************************************;
 | 
			
		||||
;	GotoXY ()
 | 
			
		||||
;		- Set current X/Y location
 | 
			
		||||
;	parm\	AL=X position
 | 
			
		||||
;	parm\	AH=Y position
 | 
			
		||||
;**************************************************;
 | 
			
		||||
 | 
			
		||||
bits 32
 | 
			
		||||
 | 
			
		||||
GotoXY:
 | 
			
		||||
	pusha
 | 
			
		||||
	mov	[_CurX], al		; just set the current position
 | 
			
		||||
	mov	[_CurY], ah
 | 
			
		||||
	popa
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
%endif ;__STDIO_INC_67343546FDCC56AAB872_INCLUDED__
 | 
			
		||||
							
								
								
									
										52
									
								
								timer.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								timer.c
									
									
									
									
									
								
							@@ -1,52 +0,0 @@
 | 
			
		||||
#include<system.h>
 | 
			
		||||
int timer_ticks = 0;
 | 
			
		||||
int timer_hz;
 | 
			
		||||
 | 
			
		||||
void timer_phase(int hz)
 | 
			
		||||
{
 | 
			
		||||
      int divisor = 1193180/hz;           // 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
 | 
			
		||||
      timer_hz = hz;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void timer_clock (int x, int y, int secs)
 | 
			
		||||
{
 | 
			
		||||
      int s, m, h;
 | 
			
		||||
      char arr[9] = {0,0,0,0,0,0,0,0,0};
 | 
			
		||||
      
 | 
			
		||||
      s = secs%60;
 | 
			
		||||
      m = (secs/60)%60;
 | 
			
		||||
      h = secs/3600;
 | 
			
		||||
      
 | 
			
		||||
      arr[0] = (h/10)%10 + '0'; if (arr[0]=='0') arr[0] = ' ';
 | 
			
		||||
      arr[1] = h%10 + '0';
 | 
			
		||||
      
 | 
			
		||||
      arr[3] = (m/10) + '0';
 | 
			
		||||
      arr[4] = m%10 + '0';
 | 
			
		||||
      
 | 
			
		||||
      arr[6] = s/10 + '0';
 | 
			
		||||
      arr[7] = s%10 + '0';
 | 
			
		||||
      
 | 
			
		||||
      if (secs%2 == 0) {
 | 
			
		||||
            arr[2] = ' ';
 | 
			
		||||
            arr[5] = ' ';
 | 
			
		||||
            }
 | 
			
		||||
      else {
 | 
			
		||||
            arr[2] = ':';
 | 
			
		||||
            arr[5] = ':';
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
      puts_pos(x, y, arr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void timer_handler(regs *r)
 | 
			
		||||
{
 | 
			
		||||
      timer_ticks++;
 | 
			
		||||
      
 | 
			
		||||
      if (timer_ticks % timer_hz) {
 | 
			
		||||
            timer_clock (70, 0, timer_ticks / timer_hz);
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user