OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /eco32/tags/eco32-0.26/hwtests/kbdtest
    from Rev 245 to Rev 270
    Reverse comparison

Rev 245 → Rev 270

/Makefile
0,0 → 1,27
#
# Makefile for kbdtest ROM
#
 
BUILD = ../../build
 
KBDTEST_SRC = start.s main.c lib.c serial.s end.s
 
.PHONY: all install run clean
 
all: kbdtest.exo
 
install: kbdtest.exo
 
kbdtest.exo: kbdtest.bin
$(BUILD)/bin/bin2exo -S2 0 kbdtest.bin kbdtest.exo
 
kbdtest.bin: $(KBDTEST_SRC)
$(BUILD)/bin/lcc -A -Wo-rom -Wl-rd -Wl0xC03F0000 \
-Wl-m -Wlkbdtest.map -o kbdtest.bin $(KBDTEST_SRC)
 
run: kbdtest.bin
$(BUILD)/bin/sim -i -c -s 1 -t 0 -r kbdtest.bin
 
clean:
rm -f *~
rm -f kbdtest.map kbdtest.bin kbdtest.exo
/README
0,0 → 1,5
This is a test for the keyboard. After initializing the interrupt
system, the program waits for keyboard interrupts. As soon as a byte
is sent by the keyboard, its hex representation is output on serial
line 0 (as are the initialization messages). If you run this test on
the simulator, be sure to give the input focus to the console screen.
/serial.s
0,0 → 1,98
;
; serial.s -- the serial line interface
;
 
;***************************************************************
 
.set ser0base,0xF0300000 ; serial line 0 base address
.set ser1base,0xF0301000 ; serial line 1 base address
 
.export serinit ; initialize serial interface
 
.export ser0inchk ; line 0 input check
.export ser0in ; line 0 input
.export ser0outchk ; line 0 output check
.export ser0out ; line 0 output
 
.export ser1inchk ; line 1 input check
.export ser1in ; line 1 input
.export ser1outchk ; line 1 output check
.export ser1out ; line 1 output
 
;***************************************************************
 
.code
.align 4
 
serinit:
jr $31
 
;***************************************************************
 
.code
.align 4
 
ser0inchk:
add $8,$0,ser0base
ldw $2,$8,0
and $2,$2,1
jr $31
 
ser0in:
add $8,$0,ser0base
ser0in1:
ldw $9,$8,0
and $9,$9,1
beq $9,$0,ser0in1
ldw $2,$8,4
jr $31
 
ser0outchk:
add $8,$0,ser0base
ldw $2,$8,8
and $2,$2,1
jr $31
 
ser0out:
add $8,$0,ser0base
ser0out1:
ldw $9,$8,8
and $9,$9,1
beq $9,$0,ser0out1
stw $4,$8,12
jr $31
 
;***************************************************************
 
.code
.align 4
 
ser1inchk:
add $8,$0,ser1base
ldw $2,$8,0
and $2,$2,1
jr $31
 
ser1in:
add $8,$0,ser1base
ser1in1:
ldw $9,$8,0
and $9,$9,1
beq $9,$0,ser1in1
ldw $2,$8,4
jr $31
 
ser1outchk:
add $8,$0,ser1base
ldw $2,$8,8
and $2,$2,1
jr $31
 
ser1out:
add $8,$0,ser1base
ser1out1:
ldw $9,$8,8
and $9,$9,1
beq $9,$0,ser1out1
stw $4,$8,12
jr $31
/main.c
0,0 → 1,129
/*
* main.c -- the main program
*/
 
 
#include "common.h"
#include "lib.h"
#include "start.h"
 
 
int charAvail = 0;
char charRead;
 
 
/**************************************************************/
 
 
/*
* Interrupt and exception messages which will be shown if
* the corresponding interrupt or exception is not handled.
*/
char *exceptionCause[32] = {
/* 00 */ "terminal 0 transmitter interrupt",
/* 01 */ "terminal 0 receiver interrupt",
/* 02 */ "terminal 1 transmitter interrupt",
/* 03 */ "terminal 1 receiver interrupt",
/* 04 */ "keyboard interrupt",
/* 05 */ "unknown interrupt 5",
/* 06 */ "unknown interrupt 6",
/* 07 */ "unknown interrupt 7",
/* 08 */ "disk interrupt",
/* 09 */ "unknown interrupt 9",
/* 10 */ "unknown interrupt 10",
/* 11 */ "unknown interrupt 11",
/* 12 */ "unknown interrupt 12",
/* 13 */ "unknown interrupt 13",
/* 14 */ "timer 0 interrupt",
/* 15 */ "timer 1 interrupt",
/* 16 */ "bus timeout exception",
/* 17 */ "illegal instruction exception",
/* 18 */ "privileged instruction exception",
/* 19 */ "divide instruction exception",
/* 20 */ "trap instruction exception",
/* 21 */ "TLB miss exception",
/* 22 */ "TLB write exception",
/* 23 */ "TLB invalid exception",
/* 24 */ "illegal address exception",
/* 25 */ "privileged address exception",
/* 26 */ "unknown exception 26",
/* 27 */ "unknown exception 27",
/* 28 */ "unknown exception 28",
/* 29 */ "unknown exception 29",
/* 30 */ "unknown exception 30",
/* 31 */ "unknown exception 31"
};
 
 
/*
* This is the default interrupt service routine.
* It simply panics with a message that tells the cause.
*/
void defaultISR(int irq, InterruptContext *icp) {
printf("**** %s ****\n", exceptionCause[irq]);
while (1) ;
}
 
 
/*
* Initialize all interrupts and exceptions to the default ISR.
* Enable interrupts.
*/
void initInterrupts(void) {
int i;
 
for (i = 0; i < 32; i++) {
setISR(i, defaultISR);
}
enable();
}
 
 
/**************************************************************/
 
 
void kbdISR(int irq, InterruptContext *icp) {
unsigned int *p;
 
p = (unsigned int *) 0xF0200000;
charRead = *(p + 1);
charAvail = 1;
}
 
 
void kbdEnable(void) {
unsigned int *p;
 
p = (unsigned int *) 0xF0200000;
*p = 2;
}
 
 
int main(void) {
unsigned char c;
int n;
 
printf("Keyboard Test:\n");
printf("initializing interrupts...\n");
initInterrupts();
printf("setting kbd ISR...\n");
setISR(4, kbdISR);
printf("enabling kbd interrupt mask bit...\n");
setMask(getMask() | (1 << 4));
printf("enabling interrupts in kbd controller...\n");
kbdEnable();
n = 0;
while (1) {
while (charAvail == 0) ;
disable();
c = charRead;
charAvail = 0;
enable();
printf("%02X ", c);
if (++n == 24) {
n = 0;
printf("\n");
}
}
return 0;
}
/start.s
0,0 → 1,384
;
; start.s -- startup and support routines
;
 
.set dmapaddr,0xC0000000 ; base of directly mapped addresses
.set stacktop,0xC0400000 ; monitor stack is at top of memory
 
.set ICNTXT_SIZE,34 * 4 ; size of interrupt context
 
.set PSW,0 ; reg # of PSW
.set V_SHIFT,27 ; interrupt vector ctrl bit
.set V,1 << V_SHIFT
.set UM_SHIFT,26 ; curr user mode ctrl bit
.set UM,1 << UM_SHIFT
.set PUM_SHIFT,25 ; prev user mode ctrl bit
.set PUM,1 << PUM_SHIFT
.set OUM_SHIFT,24 ; old user mode ctrl bit
.set OUM,1 << OUM_SHIFT
.set IE_SHIFT,23 ; curr int enable ctrl bit
.set IE,1 << IE_SHIFT
.set PIE_SHIFT,22 ; prev int enable ctrl bit
.set PIE,1 << PIE_SHIFT
.set OIE_SHIFT,21 ; old int enable ctrl bit
.set OIE,1 << OIE_SHIFT
 
.set TLB_INDEX,1 ; reg # of TLB Index
.set TLB_ENTRY_HI,2 ; reg # of TLB EntryHi
.set TLB_ENTRY_LO,3 ; reg # of TLB EntryLo
.set TLB_ENTRIES,32 ; number of TLB entries
 
;***************************************************************
 
.import _ecode
.import _edata
.import _ebss
 
.import serinit
.import ser0in
.import ser0out
 
.import main
 
.export _bcode
.export _bdata
.export _bbss
 
.export cin
.export cout
 
.export getTLB_HI
.export getTLB_LO
.export setTLB
.export wrtRndTLB
.export probeTLB
.export wait
 
.export enable
.export disable
.export getMask
.export setMask
.export getISR
.export setISR
 
;***************************************************************
 
.code
_bcode:
 
.data
_bdata:
 
.bss
_bbss:
 
;***************************************************************
 
.code
.align 4
 
reset:
j start
 
interrupt:
j isr
 
userMiss:
j userMiss
 
;***************************************************************
 
.code
.align 4
 
cin:
j ser0in
 
cout:
j ser0out
 
;***************************************************************
 
.code
.align 4
 
start:
; force CPU into a defined state
mvts $0,PSW ; disable interrupts and user mode
 
; initialize TLB
mvts $0,TLB_ENTRY_LO ; invalidate all TLB entries
add $8,$0,dmapaddr ; by impossible virtual page number
add $9,$0,$0
add $10,$0,TLB_ENTRIES
tlbloop:
mvts $8,TLB_ENTRY_HI
mvts $9,TLB_INDEX
tbwi
add $8,$8,0x1000 ; all entries must be different
add $9,$9,1
bne $9,$10,tlbloop
 
; copy data segment
add $10,$0,_bdata ; lowest dst addr to be written to
add $8,$0,_edata ; one above the top dst addr
sub $9,$8,$10 ; $9 = size of data segment
add $9,$9,_ecode ; data is waiting right after code
j cpytest
cpyloop:
ldw $11,$9,0 ; src addr in $9
stw $11,$8,0 ; dst addr in $8
cpytest:
sub $8,$8,4 ; downward
sub $9,$9,4
bgeu $8,$10,cpyloop
 
; clear bss segment
add $8,$0,_bbss ; start with first word of bss
add $9,$0,_ebss ; this is one above the top
j clrtest
clrloop:
stw $0,$8,0 ; dst addr in $8
add $8,$8,4 ; upward
clrtest:
bltu $8,$9,clrloop
 
; now do some useful work
add $29,$0,stacktop ; setup monitor stack
jal serinit ; init serial interface
jal main ; enter command loop
 
; main should never return
j start ; just to be sure...
 
;***************************************************************
 
; Word getTLB_HI(int index)
getTLB_HI:
mvts $4,TLB_INDEX
tbri
mvfs $2,TLB_ENTRY_HI
jr $31
 
; Word getTLB_LO(int index)
getTLB_LO:
mvts $4,TLB_INDEX
tbri
mvfs $2,TLB_ENTRY_LO
jr $31
 
; void setTLB(int index, Word entryHi, Word entryLo)
setTLB:
mvts $4,TLB_INDEX
mvts $5,TLB_ENTRY_HI
mvts $6,TLB_ENTRY_LO
tbwi
jr $31
 
; void wrtRndTLB(Word entryHi, Word entryLo)
wrtRndTLB:
mvts $4,TLB_ENTRY_HI
mvts $5,TLB_ENTRY_LO
tbwr
jr $31
 
; Word probeTLB(Word entryHi)
probeTLB:
mvts $4,TLB_ENTRY_HI
tbs
mvfs $2,TLB_INDEX
jr $31
 
; void wait(int n)
wait:
j wait2
wait1:
add $4,$4,$0
sub $4,$4,1
wait2:
bne $4,$0,wait1
jr $31
 
;***************************************************************
 
.code
.align 4
 
; void enable(void)
enable:
mvfs $8,PSW
or $8,$8,IE
mvts $8,PSW
jr $31
 
; void disable(void)
disable:
mvfs $8,PSW
and $8,$8,~IE
mvts $8,PSW
jr $31
 
; U32 getMask(void)
getMask:
mvfs $8,PSW
and $2,$8,0x0000FFFF ; return lower 16 bits only
jr $31
 
; U32 setMask(U32 mask)
setMask:
mvfs $8,PSW
and $2,$8,0x0000FFFF ; return lower 16 bits only
and $4,$4,0x0000FFFF ; use lower 16 bits only
and $8,$8,0xFFFF0000
or $8,$8,$4
mvts $8,PSW
jr $31
 
; ISR getISR(int irq)
getISR:
sll $4,$4,2
ldw $2,$4,irqsrv
jr $31
 
; ISR setISR(int irq, ISR isr)
setISR:
sll $4,$4,2
ldw $2,$4,irqsrv
stw $5,$4,irqsrv
jr $31
 
;***************************************************************
 
.code
.align 4
 
; general interrupt service routine
; only register $28 is available for bootstrapping
isr:
.nosyn
add $28,$29,$0
sub $28,$28,ICNTXT_SIZE ; $28 points to interrupt context
stw $0,$28,0*4 ; save registers
stw $1,$28,1*4
stw $2,$28,2*4
stw $3,$28,3*4
stw $4,$28,4*4
stw $5,$28,5*4
stw $6,$28,6*4
stw $7,$28,7*4
stw $8,$28,8*4
stw $9,$28,9*4
stw $10,$28,10*4
stw $11,$28,11*4
stw $12,$28,12*4
stw $13,$28,13*4
stw $14,$28,14*4
stw $15,$28,15*4
stw $16,$28,16*4
stw $17,$28,17*4
stw $18,$28,18*4
stw $19,$28,19*4
stw $20,$28,20*4
stw $21,$28,21*4
stw $22,$28,22*4
stw $23,$28,23*4
stw $24,$28,24*4
stw $25,$28,25*4
stw $26,$28,26*4
stw $27,$28,27*4
stw $28,$28,28*4
stw $29,$28,29*4
stw $30,$28,30*4
stw $31,$28,31*4
mvfs $8,TLB_ENTRY_HI ; save TLB EntryHi
stw $8,$28,32*4
mvfs $8,PSW ; save PSW
stw $8,$28,33*4
add $29,$28,$0 ; $29 is required to hold sp
.syn
add $5,$29,$0 ; $5 = pointer to interrupt context
slr $4,$8,16 ; $4 = IRQ number
and $4,$4,0x1F
sll $8,$4,2 ; $8 = 4 * IRQ number
ldw $8,$8,irqsrv ; get addr of service routine
jalr $8 ; call service routine
.nosyn
mvts $0,PSW ; ISR may have enabled interrupts
add $28,$29,$0 ; $28 points to interrupt context
ldw $8,$28,32*4 ; restore TLB EntryHi
mvts $8,TLB_ENTRY_HI
ldw $0,$28,0*4 ; restore registers
ldw $1,$28,1*4
ldw $2,$28,2*4
ldw $3,$28,3*4
ldw $4,$28,4*4
ldw $5,$28,5*4
ldw $6,$28,6*4
ldw $7,$28,7*4
ldw $8,$28,8*4
ldw $9,$28,9*4
ldw $10,$28,10*4
ldw $11,$28,11*4
ldw $12,$28,12*4
ldw $13,$28,13*4
ldw $14,$28,14*4
ldw $15,$28,15*4
ldw $16,$28,16*4
ldw $17,$28,17*4
ldw $18,$28,18*4
ldw $19,$28,19*4
ldw $20,$28,20*4
ldw $21,$28,21*4
ldw $22,$28,22*4
ldw $23,$28,23*4
ldw $24,$28,24*4
ldw $25,$28,25*4
ldw $26,$28,26*4
ldw $27,$28,27*4
ldw $28,$28,28*4
ldw $29,$28,29*4
ldw $30,$28,30*4
ldw $31,$28,31*4
ldw $28,$28,33*4 ; restore PSW
mvts $28,PSW
rfx ; done
.syn
 
;***************************************************************
 
.data
.align 4
 
irqsrv:
.word 0 ; 00: terminal 0 transmitter interrupt
.word 0 ; 01: terminal 0 receiver interrupt
.word 0 ; 02: terminal 1 transmitter interrupt
.word 0 ; 03: terminal 1 receiver interrupt
.word 0 ; 04: keyboard interrupt
.word 0 ; 05: unused
.word 0 ; 06: unused
.word 0 ; 07: unused
.word 0 ; 08: disk interrupt
.word 0 ; 09: unused
.word 0 ; 10: unused
.word 0 ; 11: unused
.word 0 ; 12: unused
.word 0 ; 13: unused
.word 0 ; 14: timer 0 interrupt
.word 0 ; 15: timer 1 interrupt
.word 0 ; 16: bus timeout exception
.word 0 ; 17: illegal instruction exception
.word 0 ; 18: privileged instruction exception
.word 0 ; 19: divide instruction exception
.word 0 ; 20: trap instruction exception
.word 0 ; 21: TLB miss exception
.word 0 ; 22: TLB write exception
.word 0 ; 23: TLB invalid exception
.word 0 ; 24: illegal address exception
.word 0 ; 25: privileged address exception
.word 0 ; 26: unused
.word 0 ; 27: unused
.word 0 ; 28: unused
.word 0 ; 29: unused
.word 0 ; 30: unused
.word 0 ; 31: unused
/start.h
0,0 → 1,36
/*
* start.h -- startup and support routines
*/
 
 
#ifndef _START_H_
#define _START_H_
 
 
typedef struct {
Word ic_reg[32]; /* general purpose registers */
Word ic_tlbhi; /* TLB EntryHi */
Word ic_psw; /* PSW */
} InterruptContext;
 
typedef void (*ISR)(int irq, InterruptContext *icp);
 
 
int cin(void);
void cout(char c);
 
Word getTLB_HI(int index);
Word getTLB_LO(int index);
void setTLB(int index, Word entryHi, Word entryLo);
void wrtRndTLB(Word entryHi, Word entryLo);
Word probeTLB(Word entryHi);
void wait(int n);
void enable(void);
void disable(void);
Word getMask(void);
Word setMask(Word mask);
ISR getISR(int irq);
ISR setISR(int irq, ISR isr);
 
 
#endif /* _START_H_ */
/end.s
0,0 → 1,19
;
; end.s -- end-of-segment labels
;
 
.export _ecode
.export _edata
.export _ebss
 
.code
.align 4
_ecode:
 
.data
.align 4
_edata:
 
.bss
.align 4
_ebss:
/lib.c
0,0 → 1,624
/*
* lib.c -- the library
*/
 
 
#include "common.h"
#include "lib.h"
#include "stdarg.h"
#include "start.h"
 
 
/**************************************************************/
 
 
/*
* This is only for debugging.
* Place a breakpoint at the very beginning of this routine
* and call it wherever you want to break execution.
*/
void debugBreak(void) {
}
 
 
/**************************************************************/
 
 
/*
* Count the length of a string (without terminating null character).
*/
int strlen(const char *s) {
const char *p;
 
p = s;
while (*p != '\0') {
p++;
}
return p - s;
}
 
 
/*
* Compare two strings.
* Return a number < 0, = 0, or > 0 iff the first string is less
* than, equal to, or greater than the second one, respectively.
*/
int strcmp(const char *s, const char *t) {
while (*s == *t) {
if (*s == '\0') {
return 0;
}
s++;
t++;
}
return *s - *t;
}
 
 
/*
* Copy string t to string s (includes terminating null character).
*/
char *strcpy(char *s, const char *t) {
char *p;
 
p = s;
while ((*p = *t) != '\0') {
p++;
t++;
}
return s;
}
 
 
/*
* Append string t to string s.
*/
char *strcat(char *s, const char *t) {
char *p;
 
p = s;
while (*p != '\0') {
p++;
}
while ((*p = *t) != '\0') {
p++;
t++;
}
return s;
}
 
 
/*
* Locate character c in string s.
*/
char *strchr(const char *s, char c) {
while (*s != c) {
if (*s == '\0') {
return NULL;
}
s++;
}
return (char *) s;
}
 
 
/*
* Extract the next token from the string s, delimited
* by any character from the delimiter string t.
*/
char *strtok(char *s, const char *t) {
static char *p;
char *q;
 
if (s != NULL) {
p = s;
} else {
p++;
}
while (*p != '\0' && strchr(t, *p) != NULL) {
p++;
}
if (*p == '\0') {
return NULL;
}
q = p++;
while (*p != '\0' && strchr(t, *p) == NULL) {
p++;
}
if (*p != '\0') {
*p = '\0';
} else {
p--;
}
return q;
}
 
 
/**************************************************************/
 
 
/*
* Determine if a character is 'white space'.
*/
static Bool isspace(char c) {
Bool res;
 
switch (c) {
case ' ':
case '\f':
case '\n':
case '\r':
case '\t':
case '\v':
res = true;
break;
default:
res = false;
break;
}
return res;
}
 
 
/*
* Check for valid digit, and convert to value.
*/
static Bool checkDigit(char c, int base, int *value) {
if (c >= '0' && c <= '9') {
*value = c - '0';
} else
if (c >= 'A' && c <= 'Z') {
*value = c - 'A' + 10;
} else
if (c >= 'a' && c <= 'z') {
*value = c - 'a' + 10;
} else {
return false;
}
return *value < base;
}
 
 
/*
* Convert initial part of string to unsigned long integer.
*/
unsigned long strtoul(const char *s, char **endp, int base) {
unsigned long res;
int sign;
int digit;
 
res = 0;
while (isspace(*s)) {
s++;
}
if (*s == '+') {
sign = 1;
s++;
} else
if (*s == '-') {
sign = -1;
s++;
} else {
sign = 1;
}
if (base == 0 || base == 16) {
if (*s == '0' &&
(*(s + 1) == 'x' || *(s + 1) == 'X')) {
/* base is 16 */
s += 2;
base = 16;
} else {
/* base is 0 or 16, but number does not start with "0x" */
if (base == 0) {
if (*s == '0') {
s++;
base = 8;
} else {
base = 10;
}
} else {
/* take base as is */
}
}
} else {
/* take base as is */
}
while (checkDigit(*s, base, &digit)) {
res *= base;
res += digit;
s++;
}
if (endp != NULL) {
*endp = (char *) s;
}
return sign * res;
}
 
 
/**************************************************************/
 
 
/*
* Exchange two array items of a given size.
*/
static void xchg(char *p, char *q, int size) {
char t;
 
while (size--) {
t = *p;
*p++ = *q;
*q++ = t;
}
}
 
 
/*
* This is a recursive version of quicksort.
*/
static void sort(char *l, char *r, int size,
int (*cmp)(const void *, const void *)) {
char *i;
char *j;
char *x;
 
i = l;
j = r;
x = l + (((r - l) / size) / 2) * size;
do {
while (cmp(i, x) < 0) {
i += size;
}
while (cmp(x, j) < 0) {
j -= size;
}
if (i <= j) {
/* exchange array elements i and j */
/* attention: update x if it is one of these */
if (x == i) {
x = j;
} else
if (x == j) {
x = i;
}
xchg(i, j, size);
i += size;
j -= size;
}
} while (i <= j);
if (l < j) {
sort(l, j, size, cmp);
}
if (i < r) {
sort(i, r, size, cmp);
}
}
 
 
/*
* External interface for the quicksort algorithm.
*/
void qsort(void *base, int n, int size,
int (*cmp)(const void *, const void*)) {
sort((char *) base, (char *) base + (n - 1) * size, size, cmp);
}
 
 
/**************************************************************/
 
 
/*
* Input a character from the console.
*/
char getchar(void) {
return cin();
}
 
 
/*
* Output a character on the console.
* Replace LF by CR/LF.
*/
void putchar(char c) {
if (c == '\n') {
cout('\r');
}
cout(c);
}
 
 
/**************************************************************/
 
 
/*
* Count the number of characters needed to represent
* a given number in base 10.
*/
static int countPrintn(long n) {
long a;
int res;
 
res = 0;
if (n < 0) {
res++;
n = -n;
}
a = n / 10;
if (a != 0) {
res += countPrintn(a);
}
return res + 1;
}
 
 
/*
* Output a number in base 10.
*/
static void *printn(void *(*emit)(void *, char), void *arg,
int *nchar, long n) {
long a;
 
if (n < 0) {
arg = emit(arg, '-');
(*nchar)++;
n = -n;
}
a = n / 10;
if (a != 0) {
arg = printn(emit, arg, nchar, a);
}
arg = emit(arg, n % 10 + '0');
(*nchar)++;
return arg;
}
 
 
/*
* Count the number of characters needed to represent
* a given number in a given base.
*/
static int countPrintu(unsigned long n, unsigned long b) {
unsigned long a;
int res;
 
res = 0;
a = n / b;
if (a != 0) {
res += countPrintu(a, b);
}
return res + 1;
}
 
 
/*
* Output a number in a given base.
*/
static void *printu(void *(*emit)(void *, char), void *arg,
int *nchar, unsigned long n, unsigned long b,
Bool upperCase) {
unsigned long a;
 
a = n / b;
if (a != 0) {
arg = printu(emit, arg, nchar, a, b, upperCase);
}
if (upperCase) {
arg = emit(arg, "0123456789ABCDEF"[n % b]);
(*nchar)++;
} else {
arg = emit(arg, "0123456789abcdef"[n % b]);
(*nchar)++;
}
return arg;
}
 
 
/*
* Output a number of filler characters.
*/
static void *fill(void *(*emit)(void *, char), void *arg,
int *nchar, int numFillers, char filler) {
while (numFillers-- > 0) {
arg = emit(arg, filler);
(*nchar)++;
}
return arg;
}
 
 
/*
* This function does the real work of formatted printing.
*/
static int doPrintf(void *(*emit)(void *, char), void *arg,
const char *fmt, va_list ap) {
int nchar;
char c;
int n;
long ln;
unsigned int u;
unsigned long lu;
char *s;
Bool negFlag;
char filler;
int width, count;
 
nchar = 0;
while (1) {
while ((c = *fmt++) != '%') {
if (c == '\0') {
return nchar;
}
arg = emit(arg, c);
nchar++;
}
c = *fmt++;
if (c == '-') {
negFlag = true;
c = *fmt++;
} else {
negFlag = false;
}
if (c == '0') {
filler = '0';
c = *fmt++;
} else {
filler = ' ';
}
width = 0;
while (c >= '0' && c <= '9') {
width *= 10;
width += c - '0';
c = *fmt++;
}
if (c == 'd') {
n = va_arg(ap, int);
count = countPrintn(n);
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
arg = printn(emit, arg, &nchar, n);
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
u = va_arg(ap, int);
count = countPrintu(u,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
arg = printu(emit, arg, &nchar, u,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
c == 'X');
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else
if (c == 'l') {
c = *fmt++;
if (c == 'd') {
ln = va_arg(ap, long);
count = countPrintn(ln);
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
arg = printn(emit, arg, &nchar, ln);
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
lu = va_arg(ap, long);
count = countPrintu(lu,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
arg = printu(emit, arg, &nchar, lu,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
c == 'X');
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else {
arg = emit(arg, 'l');
nchar++;
arg = emit(arg, c);
nchar++;
}
} else
if (c == 's') {
s = va_arg(ap, char *);
count = strlen(s);
if (width > 0 && !negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
while ((c = *s++) != '\0') {
arg = emit(arg, c);
nchar++;
}
if (width > 0 && negFlag) {
arg = fill(emit, arg, &nchar, width - count, filler);
}
} else
if (c == 'c') {
c = va_arg(ap, char);
arg = emit(arg, c);
nchar++;
} else {
arg = emit(arg, c);
nchar++;
}
}
/* never reached */
return 0;
}
 
 
/*
* Emit a character to the console.
*/
static void *emitToConsole(void *dummy, char c) {
putchar(c);
return dummy;
}
 
 
/*
* Formatted output with a variable argument list.
*/
static int vprintf(const char *fmt, va_list ap) {
int n;
 
n = doPrintf(emitToConsole, NULL, fmt, ap);
return n;
}
 
 
/*
* Formatted output.
*/
int printf(const char *fmt, ...) {
int n;
va_list ap;
 
va_start(ap, fmt);
n = vprintf(fmt, ap);
va_end(ap);
return n;
}
 
 
/*
* Emit a character to a buffer.
*/
static void *emitToBuffer(void *bufptr, char c) {
*(char *)bufptr = c;
return (char *) bufptr + 1;
}
 
 
/*
* Formatted output into a buffer with a variable argument list.
*/
static int vsprintf(char *s, const char *fmt, va_list ap) {
int n;
 
n = doPrintf(emitToBuffer, s, fmt, ap);
s[n] = '\0';
return n;
}
 
 
/*
* Formatted output into a buffer.
*/
int sprintf(char *s, const char *fmt, ...) {
int n;
va_list ap;
 
va_start(ap, fmt);
n = vsprintf(s, fmt, ap);
va_end(ap);
return n;
}
/stdarg.h
0,0 → 1,41
/*
* stdarg.h -- variable argument lists
*/
 
 
#ifndef _STDARG_H_
#define _STDARG_H_
 
 
typedef char *va_list;
 
 
static float __va_arg_tmp;
 
 
#define va_start(list, start) \
((void)((list) = (sizeof(start)<4 ? \
(char *)((int *)&(start)+1) : (char *)(&(start)+1))))
 
#define __va_arg(list, mode, n) \
(__typecode(mode)==1 && sizeof(mode)==4 ? \
(__va_arg_tmp = *(double *)(&(list += \
((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \
*(mode *)&__va_arg_tmp) : \
*(mode *)(&(list += \
((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)]))
 
#define _bigendian_va_arg(list, mode, n) \
(sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \
sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \
__va_arg(list, mode, n))
 
#define va_end(list) ((void)0)
 
#define va_arg(list, mode) \
(sizeof(mode)==8 ? \
*(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \
_bigendian_va_arg(list, mode, 3U))
 
 
#endif /* _STDARG_H_ */
/lib.h
0,0 → 1,31
/*
* lib.h -- the library
*/
 
 
#ifndef _LIB_H_
#define _LIB_H_
 
 
void debugBreak(void);
 
int strlen(const char *s);
int strcmp(const char *s, const char *t);
char *strcpy(char *s, const char *t);
char *strcat(char *s, const char *t);
char *strchr(const char *s, char c);
char *strtok(char *s, const char *t);
 
unsigned long strtoul(const char *s, char **endp, int base);
 
void qsort(void *base, int n, int size,
int (*cmp)(const void *, const void *));
 
char getchar(void);
void putchar(char c);
 
int printf(const char *fmt, ...);
int sprintf(char *s, const char *fmt, ...);
 
 
#endif /* _LIB_H_ */
/common.h
0,0 → 1,27
/*
* common.h -- common definitions
*/
 
 
#ifndef _COMMON_H_
#define _COMMON_H_
 
 
#define PAGE_SHIFT 12 /* log2 of page size */
#define PAGE_SIZE (1 << PAGE_SHIFT) /* page size in bytes */
#define OFFSET_MASK (PAGE_SIZE - 1) /* mask for offset in page */
#define PAGE_MASK (~OFFSET_MASK) /* mask for page number */
 
 
typedef enum { false, true } Bool; /* truth values */
 
 
typedef unsigned int Word; /* 32 bit quantities */
typedef unsigned short Half; /* 16 bit quantities */
typedef unsigned char Byte; /* 8 bit quantities */
 
 
#define NULL ((void *) 0)
 
 
#endif /* _COMMON_H_ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.