(2006-08-06) rescue-bootcd

This commit is contained in:
2006-08-06 00:00:00 +02:00
parent 2f796b816a
commit decb062d20
21091 changed files with 7076462 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
#ident "$Id: Makefile,v 1.23 2005/01/03 08:23:16 hpa Exp $"
## -----------------------------------------------------------------------
##
## Copyright 2001-2004 H. Peter Anvin - All Rights Reserved
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, Inc., 53 Temple Place Ste 330,
## Boston MA 02111-1307, USA; either version 2 of the License, or
## (at your option) any later version; incorporated herein by reference.
##
## -----------------------------------------------------------------------
##
## samples for syslinux users
##
gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \
then echo $(1); else echo $(2); fi)
M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,)
CC = gcc $(M32)
LD = ld -m elf_i386
AR = ar
NASM = nasm
RANLIB = ranlib
CFLAGS = -W -Wall -march=i386 -Os -fomit-frame-pointer -I../com32/include
SFLAGS = -march=i386
LDFLAGS = -s
OBJCOPY = objcopy
PPMTOLSS16 = ../ppmtolss16
LIB = liboldcom32.a
LIBOBJS = conio.o atou.o skipatou.o printf.o c32exit.o
.SUFFIXES: .lss .c .o .elf .c32
all: syslogo.lss comecho.com hello.c32 hello2.c32 filetest.c32 c32echo.c32 \
fd.c32 $(LIB)
.PRECIOUS: %.o
%.o: %.S
$(CC) $(SFLAGS) -c -o $@ $<
.PRECIOUS: %.o
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
.PRECIOUS: %.elf
%.elf: c32entry.o %.o $(LIB)
$(LD) -Ttext 0x101000 -e _start -o $@ $^
%.c32: %.elf
$(OBJCOPY) -O binary $< $@
%.com: %.asm
$(NASM) -f bin -o $@ -l $*.lst $<
$(LIB): $(LIBOBJS)
rm -f $@
$(AR) cq $@ $^
$(RANLIB) $@
syslogo.lss: syslogo.png $(PPMTOLSS16)
pngtopnm syslogo.png | \
$(PPMTOLSS16) \#000000=0 \#d0d0d0=7 \#f6f6f6=15 \
> syslogo.lss
tidy:
rm -f *.o *.a *.lst *.elf
# Don't specify *.com since mdiskchk.com can't be built using Linux tools
clean: tidy
rm -f *.lss *.o *.c32 comecho.com
spotless: clean

View File

@@ -0,0 +1,6 @@
This directory contains files intended to be used as sample code.
This includes COMBOOT, COM32, and MS-DOS programs as well as LSS
icons.
For developing COM32 programs, you probably want to use the new com32
toolkit (libcom32 and libutil), available in the com32 directory.

View File

@@ -0,0 +1,14 @@
static inline int
isdigit(int ch)
{
return (ch >= '0') && (ch <= '9');
}
unsigned int atou(const char *s)
{
unsigned int i = 0;
while (isdigit(*s))
i = i*10 + (*s++ - '0');
return i;
}

Binary file not shown.

View File

@@ -0,0 +1,49 @@
#ident "$Id: c32echo.c,v 1.3 2005/01/03 08:23:16 hpa Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 2002 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* c32echo.c
*
* Simple COM32 program which only prints out its own command line
*/
#include <com32.h>
#define NULL ((void *)0)
static inline void memset(void *buf, int ch, unsigned int len)
{
asm volatile("cld; rep; stosb"
: "+D" (buf), "+c" (len) : "a" (ch) : "memory");
}
int __start(void)
{
com32sys_t inreg;
const char *p;
memset(&inreg, 0, sizeof inreg);
inreg.eax.b[1] = 0x02; /* Write Character */
for ( p = __com32.cs_cmdline ; *p ; p++ ) {
inreg.edx.b[0] = *p;
__com32.cs_intcall(0x21, &inreg, NULL);
}
inreg.edx.b[0] = '\r';
__com32.cs_intcall(0x21, &inreg, NULL);
inreg.edx.b[0] = '\n';
__com32.cs_intcall(0x21, &inreg, NULL);
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,67 @@
#ident "$Id: c32entry.S,v 1.5 2005/01/03 08:23:16 hpa Exp $"
# -----------------------------------------------------------------------
#
# Copyright 2003 H. Peter Anvin - All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall
# be included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# -----------------------------------------------------------------------
# COM32 start up code - must be linked first in the binary
.section ".text","ax"
.globl _start
_start:
# This first instruction acts as COM32 magic number
movl $0x21cd4cff,%eax
# Upwards string operations
cld
# Zero the .bss segment
xorl %eax,%eax
movl $__bss_start,%edi # Symbol provided by linker
movl $_end+3,%ecx # Symbol provided by linker
subl %edi,%ecx
shrl $2,%ecx
rep ; stosl
# Copy COM32 invocation parameters
leal 4(%esp),%esi # Argument list
movl $__com32,%edi
movl $6,%ecx
movl %esp,-4(%edi) # Save the initial stack ptr
cmpl (%esi),%ecx
jbe 1f
movl (%esi),%ecx
1: rep ; movsl
# Run program; we call this __start rather than main since we
# did not parse the command line or anything like that.
jmp __start
.section ".bss","aw"
.globl __entry_esp
__entry_esp: .space 4
.globl __com32
__com32: .space 4*6

Binary file not shown.

View File

@@ -0,0 +1,10 @@
# $Id#
#
# Implementation of exit() for com32 based on c32entry.S
#
.text
.globl exit
exit:
movl 4(%esp),%eax # Exit code in %eax = return value
movl (__entry_esp),%esp # Return stack pointer to entry value
ret # Return to termination address

Binary file not shown.

View File

@@ -0,0 +1,35 @@
;
; Simple COMBOOT program that just prints out its own command line.
; This also works in DOS.
;
org 100h
_start:
xor cx,cx
mov cl,[80h] ; Command line len
mov si,81h ; Command line
mov dl,"<"
mov ah,02h
int 21h
.writechar:
lodsb
mov dl,al
mov ah,02h
int 21h
loop .writechar
mov dx,end_str
mov ah,09h
int 21h
; Exit with near return, INT 20h, or INT 21h AX=4C00h
ret
end_str db ">", 0Dh, 0Ah, "$"

Binary file not shown.

View File

@@ -0,0 +1,61 @@
#ident "$Id: conio.c,v 1.4 2005/01/03 08:23:16 hpa Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 2001-2003 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* conio.c
*
* Output to the screen
*/
#include <com32.h>
#include <stdarg.h>
#define NULL ((void *)0)
static inline void memset(void *buf, int ch, unsigned int len)
{
asm volatile("cld; rep; stosb"
: "+D" (buf), "+c" (len) : "a" (ch) : "memory");
}
int putchar(int ch)
{
com32sys_t regs;
memset(&regs, 0, sizeof regs);
if ( ch == '\n' ) {
/* \n -> \r\n */
putchar('\r');
}
regs.eax.b[1] = 0x02;
regs.edx.b[0] = ch;
__com32.cs_intcall(0x21, &regs, NULL);
return ch;
}
/* Note: doesn't put '\n' like the stdc version does */
int puts(const char *s)
{
int count = 0;
while ( *s ) {
putchar(*s);
count++;
s++;
}
return count;
}

Binary file not shown.

View File

@@ -0,0 +1,63 @@
#ident "$Id: fd.c,v 1.2 2004/12/14 22:46:25 hpa Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 2003 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* fd.c
*
* Chainload a floppy disk (currently rather braindead.)
*/
#include <com32.h>
#define NULL ((void *)0)
int printf(const char *, ...);
unsigned int atou(const char *);
int __start(void)
{
int whichfd = atou(__com32.cs_cmdline);
static com32sys_t inreg, outreg; /* In bss, so zeroed automatically */
int retry;
for ( retry = 0 ; retry < 6 ; retry++ ) {
printf(">");
inreg.eax.w[0] = 0x0201; /* Read one sector */
inreg.ecx.w[0] = 0x0001; /* Cyl 0 sector 1 */
inreg.edx.b[1] = 0; /* Head 0 */
inreg.edx.b[0] = whichfd; /* Drive number */
inreg.es = SEG(__com32.cs_bounce); /* Read into the bounce buffer */
inreg.ebx.w[0] = OFFS(__com32.cs_bounce);
__com32.cs_intcall(0x13, &inreg, &outreg);
if ( (outreg.eflags.l & 1) == 0 )
break;
}
if ( (outreg.eflags.l & 1) == 0 ) {
printf("!\n");
inreg.eax.w[0] = 0x000d;
inreg.edx.w[0] = 0;
inreg.edi.l = (uint32_t) __com32.cs_bounce;
inreg.ecx.l = 512;
inreg.ebx.l = whichfd & 0xff;
inreg.esi.l = 0; /* No partitions */
inreg.ds = 0; /* No partitions */
__com32.cs_intcall(0x22, &inreg, NULL);
}
/* If we get here, badness happened */
return 255;
}

BIN
extra/syslinux-3.09/sample/fd.c32 Executable file

Binary file not shown.

BIN
extra/syslinux-3.09/sample/fd.elf Executable file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,98 @@
#include <com32.h>
#include <stdarg.h>
#define NULL ((void *)0)
int printf(const char *, ...);
int putchar(int);
static inline void memset(void *buf, int ch, unsigned int len)
{
asm volatile("cld; rep; stosb"
: "+D" (buf), "+c" (len) : "a" (ch) : "memory");
}
static void strcpy(char *dst, const char *src)
{
while ( *src )
*dst++ = *src++;
*dst = '\0';
}
static void printregs(const com32sys_t *r)
{
printf("eflags = %08x ds = %04x es = %04x fs = %04x gs = %04x\n"
"eax = %08x ebx = %08x ecx = %08x edx = %08x\n"
"ebp = %08x esi = %08x edi = %08x esp = %08x\n",
r->eflags.l, r->ds, r->es, r->fs, r->gs,
r->eax.l, r->ebx.l, r->ecx.l, r->edx.l,
r->ebp.l, r->esi.l, r->edi.l, r->_unused.l);
}
int __start(void)
{
unsigned int ax,cx,si,t;
com32sys_t inreg,outreg;
char *p;
/* Test null system call */
inreg.eflags.l = 0xffffffff;
inreg.eax.l = 0x11110000;
inreg.ecx.l = 0x22222222;
inreg.edx.l = 0x33333333;
inreg.ebx.l = 0x44444444;
inreg.ebp.l = 0x55555555;
inreg.esi.l = 0x66666666;
inreg.edi.l = 0x77777777;
inreg.ds = 0xaaaa;
inreg.es = 0xbbbb;
inreg.fs = 0xcccc;
inreg.gs = 0xdddd;
printregs(&inreg);
__com32.cs_intcall(0x22, &inreg, &outreg);
printregs(&outreg);
printf("----\n");
memset(&inreg, 0, sizeof inreg);
memset(&outreg, 0, sizeof outreg);
strcpy(__com32.cs_bounce, "test.txt");
inreg.eax.w[0] = 0x0006; // Open file
inreg.esi.w[0] = OFFS(__com32.cs_bounce);
inreg.es = SEG(__com32.cs_bounce);
printregs(&inreg);
__com32.cs_intcall(0x22, &inreg, &outreg);
printregs(&outreg);
printf("----\n");
si = outreg.esi.w[0]; /* File handle */
cx = outreg.ecx.w[0]; /* Block size */
ax = outreg.eax.l; /* File length */
while ( si ) {
/* We can only read 64K per call */
t = ( ax > 65536 ) ? 65536/cx : (ax+cx-1)/cx;
memset(&inreg, 0, sizeof inreg);
inreg.esi.w[0] = si;
inreg.ecx.w[0] = t; /* Block count */
inreg.eax.w[0] = 0x0007; // Read file
inreg.ebx.w[0] = OFFS(__com32.cs_bounce);
inreg.es = SEG(__com32.cs_bounce);
printregs(&inreg);
__com32.cs_intcall(0x22, &inreg, &outreg);
printregs(&outreg);
printf("----\n");
si = outreg.esi.w[0];
/* Print the buffer */
t = (ax < 65536) ? ax : 65536;
p = __com32.cs_bounce;
while ( t ) {
putchar(*p++);
t--;
ax--;
}
}
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,45 @@
#ident "$Id: hello.c,v 1.6 2005/01/03 08:23:16 hpa Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 2002 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* hello.c
*
* Simple COM32 image
*/
#include <com32.h>
#define NULL ((void *)0)
static inline void memset(void *buf, int ch, unsigned int len)
{
asm volatile("cld; rep; stosb"
: "+D" (buf), "+c" (len) : "a" (ch) : "memory");
}
int __start(void)
{
const char *msg = "Hello, World!\r\n";
com32sys_t inreg;
const char *p;
memset(&inreg, 0, sizeof inreg);
for ( p = msg ; *p ; p++ ) {
inreg.edx.b[0] = *p;
inreg.eax.b[1] = 0x02; /* Write Character */
__com32.cs_intcall(0x21, &inreg, NULL);
}
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,61 @@
#ident "$Id: hello2.c,v 1.4 2004/12/14 22:46:25 hpa Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 2002 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* hello2.c
*
* Simple COM32 image
*
* This version shows how to use the bounce buffer for data transfer
* to the BIOS or COMBOOT system calls.
*/
#include <com32.h>
#define NULL ((void *)0)
static inline void memset(void *buf, int ch, unsigned int len)
{
asm volatile("cld; rep; stosb"
: "+D" (buf), "+c" (len) : "a" (ch) : "memory");
}
static void strcpy(char *dst, const char *src)
{
while ( *src )
*dst++ = *src++;
*dst = '\0';
}
static void writemsg(const char *msg)
{
com32sys_t inreg;
memset(&inreg, 0, sizeof inreg);
strcpy(__com32.cs_bounce, msg);
inreg.eax.w[0] = 0x0002; /* Write string */
inreg.ebx.w[0] = OFFS(__com32.cs_bounce);
inreg.es = SEG(__com32.cs_bounce);
__com32.cs_intcall(0x22, &inreg, NULL);
};
int __start(void)
{
writemsg("Hello, World!\r\n"
"cmdline = ");
writemsg(__com32.cs_cmdline);
writemsg("\r\n");
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,147 @@
/* -*- c -*- ------------------------------------------------------------- *
*
* Copyright 2003-2004 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/* $Id: mdiskchk.c,v 1.7 2004/12/30 21:57:12 hpa Exp $ */
/*
* mdiskchk.c
*
* DOS program to check for the existence of a memdisk.
*
* This program can be compiled for DOS with the OpenWatcom compiler
* (http://www.openwatcom.org/):
*
* wcl -3 -osx -mt mdiskchk.c
*/
#include <stdio.h>
#include <string.h>
#include <i86.h> /* For MK_FP() */
typedef unsigned long uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
struct memdiskinfo {
uint16_t bytes; /* Bytes from memdisk */
uint16_t version; /* Memdisk version */
uint32_t base; /* Base of disk in high memory */
uint32_t size; /* Size of disk in sectors */
char far * cmdline; /* Command line */
void far * oldint13; /* Old INT 13h */
void far * oldint15; /* Old INT 15h */
uint16_t olddosmem;
uint8_t bootloaderid;
uint8_t _pad;
/* We add our own fields at the end */
int cylinders;
int heads;
int sectors;
};
struct memdiskinfo * query_memdisk(int drive)
{
static struct memdiskinfo mm;
uint32_t _eax, _ebx, _ecx, _edx;
uint16_t _es, _di;
unsigned char _dl = drive;
uint16_t bytes;
__asm {
.386 ;
mov eax, 454d0800h ;
mov ecx, 444d0000h ;
mov edx, 53490000h ;
mov dl, _dl ;
mov ebx, 3f4b0000h ;
int 13h ;
mov _eax, eax ;
mov _ecx, ecx ;
mov _edx, edx ;
mov _ebx, ebx ;
mov _es, es ;
mov _di, di ;
}
if ( _eax >> 16 != 0x4d21 ||
_ecx >> 16 != 0x4d45 ||
_edx >> 16 != 0x4944 ||
_ebx >> 16 != 0x4b53 )
return NULL;
memset(&mm, 0, sizeof mm);
bytes = *(uint16_t far *)MK_FP(_es, _di);
/* 27 is the most we know how to handle */
if ( bytes > 27 )
bytes = 27;
_fmemcpy((void far *)&mm, (void far *)MK_FP(_es,_di), bytes);
mm.cylinders = ((_ecx >> 8) & 0xff) + ((_ecx & 0xc0) << 2) + 1;
mm.heads = ((_edx >> 8) & 0xff) + 1;
mm.sectors = (_ecx & 0x3f);
return &mm;
}
const char *bootloadername(uint8_t id)
{
static const struct {
uint8_t id, mask;
const char *name;
} *lp, list[] =
{
{ 0x10, 0xf0, "LILO" },
{ 0x20, 0xf0, "LOADLIN" },
{ 0x31, 0xff, "SYSLINUX" },
{ 0x32, 0xff, "PXELINUX" },
{ 0x33, 0xff, "ISOLINUX" },
{ 0x34, 0xff, "EXTLINUX" },
{ 0x30, 0xf0, "SYSLINUX family" },
{ 0x40, 0xf0, "Etherboot" },
{ 0x50, 0xf0, "ELILO" },
{ 0x70, 0xf0, "GrUB" },
{ 0x80, 0xf0, "U-Boot" },
{ 0x00, 0x00, "unknown" }
};
for ( lp = list ; ; lp++ ) {
if ( ((id ^ lp->id) & lp->mask) == 0 )
return lp->name;
}
}
int main(int argc, char *argv[])
{
int d;
int found = 0;
struct memdiskinfo *m;
for ( d = 0 ; d <= 0xff ; d++ ) {
if ( (m = query_memdisk(d)) != NULL ) {
printf("Drive %02X is MEMDISK %u.%02u:\n"
"\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n"
"\tloader = 0x%02x (%s),\n"
"\tcmdline = %Fs\n",
d, m->version >> 8, m->version & 0xff,
m->base, m->size, m->cylinders, m->heads, m->sectors,
m->bootloaderid, bootloadername(m->bootloaderid),
m->cmdline);
found++;
}
}
return found;
}

Binary file not shown.

View File

@@ -0,0 +1,307 @@
/*
* Oh, it's a waste of space, but oh-so-yummy for debugging. It's just
* initialization code anyway, so it doesn't take up space when we're
* actually running. This version of printf() does not include 64-bit
* support. "Live with it."
*
* Most of this code was shamelessly snarfed from the Linux kernel, then
* modified.
*
* FIX THIS: Replace printf() implementation with BSD/MIT-licensed one
* from klibc
*/
#include <stdarg.h>
int puts(const char *);
static inline int
isdigit(int ch)
{
return (ch >= '0') && (ch <= '9');
}
unsigned int skip_atou(const char **s);
unsigned int atou(const char *s);
static int strnlen(const char *s, int maxlen)
{
const char *es = s;
while ( *es && maxlen ) {
es++; maxlen--;
}
return (es-s);
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
#define do_div(n,base) ({ \
int __res; \
__res = ((unsigned long) n) % (unsigned) base; \
n = ((unsigned long) n) / (unsigned) base; \
__res; })
static char * number(char * str, long num, int base, int size, int precision
,int type)
{
char c,sign,tmp[66];
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
int i;
if (type & LARGE)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
if (num < 0) {
sign = '-';
num = -num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (type & SPECIAL) {
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0;
if (num == 0)
tmp[i++]='0';
else while (num != 0)
tmp[i++] = digits[do_div(num,base)];
if (i > precision)
precision = i;
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
*str++ = ' ';
if (sign)
*str++ = sign;
if (type & SPECIAL) {
if (base==8)
*str++ = '0';
else if (base==16) {
*str++ = '0';
*str++ = digits[33];
}
}
if (!(type & LEFT))
while (size-- > 0)
*str++ = c;
while (i < precision--)
*str++ = '0';
while (i-- > 0)
*str++ = tmp[i];
while (size-- > 0)
*str++ = ' ';
return str;
}
/* Forward decl. needed for IP address printing stuff... */
int sprintf(char * buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
unsigned long num;
int i, base;
char * str;
const char *s;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
for (str=buf ; *fmt ; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt) {
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
/* get field width */
field_width = -1;
if (isdigit(*fmt))
field_width = skip_atou(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.') {
++fmt;
if (isdigit(*fmt))
precision = skip_atou(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
qualifier = *fmt;
++fmt;
}
/* default base */
base = 10;
switch (*fmt) {
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
*str++ = ' ';
*str++ = (unsigned char) va_arg(args, int);
while (--field_width > 0)
*str++ = ' ';
continue;
case 's':
s = va_arg(args, char *);
len = strnlen(s, precision);
if (!(flags & LEFT))
while (len < field_width--)
*str++ = ' ';
for (i = 0; i < len; ++i)
*str++ = *s++;
while (len < field_width--)
*str++ = ' ';
continue;
case 'p':
if (field_width == -1) {
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
str = number(str,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
continue;
case 'n':
if (qualifier == 'l') {
long * ip = va_arg(args, long *);
*ip = (str - buf);
} else {
int * ip = va_arg(args, int *);
*ip = (str - buf);
}
continue;
case '%':
*str++ = '%';
continue;
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
break;
case 'X':
flags |= LARGE;
case 'x':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
*str++ = '%';
if (*fmt)
*str++ = *fmt;
else
--fmt;
continue;
}
if (qualifier == 'l')
num = va_arg(args, unsigned long);
else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
num = (short) num;
} else if (flags & SIGN)
num = va_arg(args, int);
else
num = va_arg(args, unsigned int);
str = number(str, num, base, field_width, precision, flags);
}
*str = '\0';
return str-buf;
}
int sprintf(char * buf, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i=vsprintf(buf,fmt,args);
va_end(args);
return i;
}
int printf(const char *fmt, ...)
{
char printf_buf[1024];
va_list args;
int printed;
va_start(args, fmt);
printed = vsprintf(printf_buf, fmt, args);
va_end(args);
puts(printf_buf);
return printed;
}

Binary file not shown.

View File

@@ -0,0 +1,13 @@
 $Id: sample.msg,v 1.2 2001/04/10 00:27:27 hpa Exp $
Note that <Ctrl-P>...<Ctrl-W> can be used to delimit something
that is effectively a comment.
This message is displayed before the image.
syslogo.lss
This message is displayed after the image.

Please note colors do not work quite as expected in graphics mode!

04 RED 07 02 GREEN 07 01 BLUE 07
47 RED 07 27 GREEN 07 17 BLUE 07

View File

@@ -0,0 +1,14 @@
static inline int
isdigit(int ch)
{
return (ch >= '0') && (ch <= '9');
}
unsigned int skip_atou(const char **s)
{
int i=0;
while (isdigit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB