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
 | 
					rem Compile loader
 | 
				
			||||||
%nasm_path%\nasm.exe -f aout -o %loader_name%.o %loader_name%.asm
 | 
					%nasm_path%\nasm.exe -f aout -o %loader_name%.o %loader_name%.asm
 | 
				
			||||||
rem Compile main Kernel
 | 
					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
 | 
					rem OTHER GCC/NASM SOURCES GO HERE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@echo on
 | 
					@echo on
 | 
				
			||||||
@@ -19,4 +19,5 @@ rem OTHER GCC/NASM SOURCES GO HERE
 | 
				
			|||||||
@echo Done!
 | 
					@echo Done!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pause
 | 
					@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>
 | 
					#include <system.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __CONSOLE_H
 | 
					#ifndef __CONIO_H
 | 
				
			||||||
#define __CONSOLE_H
 | 
					#define __CONIO_H
 | 
				
			||||||
#define _ATTRIB 0x0F
 | 
					#define _ATTRIB 0x0F
 | 
				
			||||||
 | 
					
 | 
				
			||||||
byte default_background, default_foreground;
 | 
					byte default_background, default_foreground;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char hex[] = "0123456789ABCDEF";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Change cursor position
 | 
					// Change cursor position
 | 
				
			||||||
void text_mode_cursor(int x, int y)
 | 
					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;
 | 
					      cursor_x = 0;
 | 
				
			||||||
      if (++cursor_y >=25) {
 | 
					      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
 | 
					// Put character on screen in the current cursor position; different font colors
 | 
				
			||||||
void putc_font(char c, byte back, byte fore)
 | 
					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)] = c;
 | 
				
			||||||
      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)+1] = fore|(back<<4);
 | 
					      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)+1] = fore|(back<<4);
 | 
				
			||||||
      cursor_x++;
 | 
					      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
 | 
					// Put character on screen in the current cursor position; default font colors
 | 
				
			||||||
void putc(char c)
 | 
					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;
 | 
					      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c;
 | 
				
			||||||
      cursor_x++;
 | 
					      cursor_x++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -125,9 +135,8 @@ void puts_font(char *str, byte back, byte fore)
 | 
				
			|||||||
            putc_font(str[i], back, 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];
 | 
					      char nr[9];
 | 
				
			||||||
      int i;
 | 
					      int i;
 | 
				
			||||||
      for (i = 7; i >= 0; i--) {
 | 
					      for (i = 7; i >= 0; i--) {
 | 
				
			||||||
@@ -135,7 +144,18 @@ void put_hex(int x, int y, unsigned int alpha)
 | 
				
			|||||||
            alpha /= 16;
 | 
					            alpha /= 16;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
      nr[8] = 0;
 | 
					      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)
 | 
					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
 | 
					*  Interrupt Controller (PICs - also called the 8259's) in
 | 
				
			||||||
*  order to make IRQ0 to 15 be remapped to IDT entries 32 to
 | 
					*  order to make IRQ0 to 15 be remapped to IDT entries 32 to
 | 
				
			||||||
*  47 */
 | 
					*  47 */
 | 
				
			||||||
void irq_remap(void)
 | 
					void irq_remap(int pic1, int pic2)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					      // Send ICW1
 | 
				
			||||||
      outportb(0x20, 0x11);
 | 
					      outportb(0x20, 0x11);
 | 
				
			||||||
      outportb(0xA0, 0x11);
 | 
					      outportb(0xA0, 0x11);
 | 
				
			||||||
      outportb(0x21, 0x20);
 | 
					      
 | 
				
			||||||
      outportb(0xA1, 0x28);
 | 
					      // send ICW2
 | 
				
			||||||
      outportb(0x21, 0x04);
 | 
					      outportb(0x21, pic1); // remap pics
 | 
				
			||||||
      outportb(0xA1, 0x02);
 | 
					      outportb(0xA1, pic2);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      // send ICW3
 | 
				
			||||||
 | 
					      outportb(0x21, 4);
 | 
				
			||||||
 | 
					      outportb(0xA1, 2);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      // Send ICW4
 | 
				
			||||||
      outportb(0x21, 0x01);
 | 
					      outportb(0x21, 0x01);
 | 
				
			||||||
      outportb(0xA1, 0x01);
 | 
					      outportb(0xA1, 0x01);
 | 
				
			||||||
      outportb(0x21, 0x0);
 | 
					      
 | 
				
			||||||
      outportb(0xA1, 0x0);
 | 
					      outportb(0x21, 0x00);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* We first remap the interrupt controllers, and then we install
 | 
					/* 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 */
 | 
					*  is just like installing the exception handlers */
 | 
				
			||||||
void irq_install()
 | 
					void irq_install()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
      irq_remap();
 | 
					      irq_remap(32,40);
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
 | 
					      idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
 | 
				
			||||||
      idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
 | 
					      idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
 | 
				
			||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
#include <system.h>
 | 
					#include <system.h>
 | 
				
			||||||
#include <console.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void isr0();
 | 
					extern void isr0();
 | 
				
			||||||
extern void isr1();
 | 
					extern void isr1();
 | 
				
			||||||
@@ -132,30 +131,30 @@ void fault_handler(regs *r)
 | 
				
			|||||||
        puts ("                              Blue Screen Of Death\n");
 | 
					        puts ("                              Blue Screen Of Death\n");
 | 
				
			||||||
        int i; for (i = 79; i>=0; i--) putc('=');
 | 
					        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 (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, 4, "gs", 0x01, 0x0B); put_hex_pos(15, 4, r->gs);
 | 
				
			||||||
        puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex(15, 5, r->fs);
 | 
					        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(15, 6, r->es);
 | 
					        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(15, 7, r->ds);
 | 
					        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, 4, "edi", 0x01, 0x0B); put_hex_pos(45, 4, r->edi);
 | 
				
			||||||
        puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex(45, 5, r->esi);
 | 
					        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(45, 6, r->ebp);
 | 
					        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(45, 7, r->esp);
 | 
					        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, 9, "eax", 0x01, 0x0B); put_hex_pos(15, 9, r->eax);
 | 
				
			||||||
        puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex(15, 10, r->ebx);
 | 
					        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(45, 9, r->ecx);
 | 
					        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(45, 10, r->edx);
 | 
					        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, 12, "int_no", 0x01, 0x0B); put_hex_pos(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, 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, 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, 17, "eip", 0x01, 0x0B); put_hex_pos(17, 17, r->eip);
 | 
				
			||||||
        puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex(17, 18, r->cs);
 | 
					        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(17, 19, r->eflags);
 | 
					        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(17, 20, r->useresp);
 | 
					        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(17, 21, r->ss);
 | 
					        puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex_pos(17, 21, r->ss);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        puts_pos_font (29, 24, "!!! System  Halted !!!", 0x01, 0x0C);
 | 
					        puts_pos_font (29, 24, "!!! System  Halted !!!", 0x01, 0x0C);
 | 
				
			||||||
        for (;;);
 | 
					        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
 | 
					      add esp, 8
 | 
				
			||||||
      iret
 | 
					      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
 | 
					SECTION .bss
 | 
				
			||||||
    resb 8192               ; This reserves 8KBytes of memory here
 | 
					    resb 8192               ; This reserves 8KBytes of memory here
 | 
				
			||||||
_sys_stack:
 | 
					_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