15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* kernel.c - the C part of the kernel */
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Copyright (C) 1999  Free Software Foundation, Inc.
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   This program is free software; you can redistribute it and/or modify
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   it under the terms of the GNU General Public License as published by
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   the Free Software Foundation; either version 2 of the License, or
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   (at your option) any later version.
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   This program is distributed in the hope that it will be useful,
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   but WITHOUT ANY WARRANTY; without even the implied warranty of
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   GNU General Public License for more details.
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   You should have received a copy of the GNU General Public License
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   along with this program; if not, write to the Free Software
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include <multiboot.h>
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Macros.  */
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Check if the bit BIT in FLAGS is set.  */
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CHECK_FLAG(flags,bit)	((flags) & (1 << (bit)))
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Some screen stuff.  */
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The number of columns.  */
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define COLUMNS			80
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The number of lines.  */
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LINES			24
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The attribute of an character.  */
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ATTRIBUTE		7
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The video memory address.  */
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define VIDEO			0xB8000
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Variables.  */
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Save the X position.  */
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int xpos;
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Save the Y position.  */
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int ypos;
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Point to the video memory.  */
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic volatile unsigned char *video;
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Forward declarations.  */
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid cmain (unsigned long magic, unsigned long addr);
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void cls (void);
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void itoa (char *buf, int base, int d);
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void putchar (int c);
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid printf (const char *format, ...);
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Check if MAGIC is valid and print the Multiboot information structure
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   pointed by ADDR.  */
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectcmain (unsigned long magic, unsigned long addr)
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  multiboot_info_t *mbi;
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Clear the screen.  */
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  cls ();
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Am I booted by a Multiboot-compliant boot loader?  */
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("Invalid magic number: 0x%x\n", (unsigned) magic);
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return;
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Set MBI to the address of the Multiboot information structure.  */
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  mbi = (multiboot_info_t *) addr;
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Print out the flags.  */
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("flags = 0x%x\n", (unsigned) mbi->flags);
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Are mem_* valid?  */
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (CHECK_FLAG (mbi->flags, 0))
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("mem_lower = %uKB, mem_upper = %uKB\n",
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Is boot_device valid?  */
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (CHECK_FLAG (mbi->flags, 1))
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device);
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Is the command line passed?  */
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (CHECK_FLAG (mbi->flags, 2))
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("cmdline = %s\n", (char *) mbi->cmdline);
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Are mods_* valid?  */
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (CHECK_FLAG (mbi->flags, 3))
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      module_t *mod;
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int i;
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("mods_count = %d, mods_addr = 0x%x\n",
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      (int) mbi->mods_count, (int) mbi->mods_addr);
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      for (i = 0, mod = (module_t *) mbi->mods_addr;
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   i < mbi->mods_count;
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   i++, mod++)
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(unsigned) mod->mod_start,
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(unsigned) mod->mod_end,
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(char *) mod->string);
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Bits 4 and 5 are mutually exclusive!  */
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("Both bits 4 and 5 are set.\n");
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return;
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Is the symbol table of a.out valid?  */
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (CHECK_FLAG (mbi->flags, 4))
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("aout_symbol_table: tabsize = 0x%0x, "
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      "strsize = 0x%x, addr = 0x%x\n",
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      (unsigned) aout_sym->tabsize,
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      (unsigned) aout_sym->strsize,
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      (unsigned) aout_sym->addr);
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Is the section header table of ELF valid?  */
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (CHECK_FLAG (mbi->flags, 5))
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("elf_sec: num = %u, size = 0x%x,"
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      " addr = 0x%x, shndx = 0x%x\n",
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      (unsigned) elf_sec->num, (unsigned) elf_sec->size,
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Are mmap_* valid?  */
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (CHECK_FLAG (mbi->flags, 6))
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      memory_map_t *mmap;
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      for (mmap = (memory_map_t *) mbi->mmap_addr;
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   mmap = (memory_map_t *) ((unsigned long) mmap
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				    + mmap->size + sizeof (mmap->size)))
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf (" size = 0x%x, base_addr = 0x%x%x,"
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		" length = 0x%x%x, type = 0x%x\n",
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(unsigned) mmap->size,
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(unsigned) mmap->base_addr_high,
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(unsigned) mmap->base_addr_low,
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(unsigned) mmap->length_high,
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(unsigned) mmap->length_low,
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(unsigned) mmap->type);
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Clear the screen and initialize VIDEO, XPOS and YPOS.  */
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectcls (void)
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int i;
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  video = (unsigned char *) VIDEO;
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i = 0; i < COLUMNS * LINES * 2; i++)
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    *(video + i) = 0;
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  xpos = 0;
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  ypos = 0;
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Convert the integer D to a string and save the string in BUF. If
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   BASE is equal to 'd', interpret that D is decimal, and if BASE is
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   equal to 'x', interpret that D is hexadecimal.  */
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectitoa (char *buf, int base, int d)
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *p = buf;
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *p1, *p2;
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long ud = d;
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int divisor = 10;
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* If %d is specified and D is minus, put `-' in the head.  */
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (base == 'd' && d < 0)
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *p++ = '-';
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      buf++;
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      ud = -d;
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else if (base == 'x')
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    divisor = 16;
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Divide UD by DIVISOR until UD == 0.  */
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  do
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int remainder = ud % divisor;
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (ud /= divisor);
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Terminate BUF.  */
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  *p = 0;
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Reverse BUF.  */
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  p1 = buf;
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  p2 = p - 1;
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (p1 < p2)
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      char tmp = *p1;
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *p1 = *p2;
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *p2 = tmp;
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      p1++;
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      p2--;
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Put the character C on the screen.  */
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectputchar (int c)
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (c == '\n' || c == '\r')
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    newline:
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      xpos = 0;
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      ypos++;
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (ypos >= LINES)
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	ypos = 0;
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return;
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  xpos++;
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (xpos >= COLUMNS)
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    goto newline;
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Format a string and print it on the screen, just like the libc
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   function printf.  */
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectprintf (const char *format, ...)
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char **arg = (char **) &format;
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int c;
2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char buf[20];
2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  arg++;
2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while ((c = *format++) != 0)
2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (c != '%')
2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	putchar (c);
2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  char *p;
2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  c = *format++;
2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  switch (c)
2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    case 'd':
2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    case 'u':
2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    case 'x':
2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      itoa (buf, c, *((int *) arg++));
2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      p = buf;
2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      goto string;
2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      break;
2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    case 's':
2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      p = *arg++;
2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (! p)
2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		p = "(null)";
2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    string:
2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      while (*p)
2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		putchar (*p++);
2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      break;
2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    default:
2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      putchar (*((int *) arg++));
2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      break;
2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
285