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/stdalone/twotasks-1
    from Rev 259 to Rev 270
    Reverse comparison

Rev 259 → Rev 270

/dump/Makefile
0,0 → 1,15
#
# Makefile for dump utility
#
 
.PHONY: all install clean
 
all: dump
 
install: dump
 
dump: dump.c
gcc -g -Wall -o dump dump.c
 
clean:
rm -f *~ dump
/dump/dump.c
0,0 → 1,48
/*
* dump.c -- dump a binary file as contents of a C array
*/
 
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
 
int main(int argc, char *argv[]) {
FILE *infile, *outfile;
int c, n;
 
if (argc != 3) {
printf("Usage: %s <infile> <outfile>\n", argv[0]);
return 1;
}
infile = fopen(argv[1], "rb");
if (infile == NULL) {
printf("Error: cannot open file '%s' for input\n", argv[1]);
return 1;
}
outfile = fopen(argv[2], "wt");
if (outfile == NULL) {
printf("Error: cannot open file '%s' for output\n", argv[2]);
return 1;
}
n = 0;
while (1) {
c = getc(infile);
if (c == EOF) {
break;
}
fprintf(outfile, "0x%02X, ", c);
n++;
if (n == 8) {
n = 0;
fprintf(outfile, "\n");
}
}
if (n != 0) {
fprintf(outfile, "\n");
}
fclose(infile);
fclose(outfile);
return 0;
}
/os/Makefile
0,0 → 1,27
BUILD = ../../../build
 
SRC = start.s main.c end.s
BIN = twotasks-1.bin
MAP = twotasks-1.map
EXO = twotasks-1.exo
 
all: $(BIN) $(EXO)
 
run: $(BIN)
$(BUILD)/bin/sim -i -s 1 -t 0 -l $(BIN) -a 0x10000
 
$(EXO): $(BIN)
$(BUILD)/bin/bin2exo -S2 0x10000 $(BIN) $(EXO)
 
$(BIN): $(SRC) task1.dump task2.dump
$(BUILD)/bin/lcc -A -Wo-kernel \
-Wl-m -Wl$(MAP) -o $(BIN) $(SRC)
 
task1.dump:
../dump/dump ../task1/task1 task1.dump
 
task2.dump:
../dump/dump ../task2/task2 task2.dump
 
clean:
rm -f *~ task1.dump task2.dump $(BIN) $(MAP) $(EXO)
/os/start.s
0,0 → 1,283
;
; start.s -- startup code
;
 
.import main
.import task0StkTop
.import currentStkTop
.import _ecode
.import _edata
.import _ebss
 
.export _bcode
.export _bdata
.export _bbss
 
.export enable
.export disable
.export orMask
.export andMask
.export getISR
.export setISR
.export startTask
.export setTLB
 
.code
_bcode:
 
.data
_bdata:
 
.bss
_bbss:
 
.code
 
; reset arrives here
reset:
j start
 
; interrupts arrive here
intrpt:
j isr
 
; user TLB misses arrive here
userMiss:
j isr
 
isr:
add $26,$29,$0 ; sp -> $26
add $27,$1,$0 ; $1 -> $27
ldw $29,$0,currentStkTop ; setup kernel mode stack
sub $29,$29,128 ; save registers
stw $2,$29,8
stw $3,$29,12
stw $4,$29,16
stw $5,$29,20
stw $6,$29,24
stw $7,$29,28
stw $8,$29,32
stw $9,$29,36
stw $10,$29,40
stw $11,$29,44
stw $12,$29,48
stw $13,$29,52
stw $14,$29,56
stw $15,$29,60
stw $16,$29,64
stw $17,$29,68
stw $18,$29,72
stw $19,$29,76
stw $20,$29,80
stw $21,$29,84
stw $22,$29,88
stw $23,$29,92
stw $24,$29,96
stw $25,$29,100
stw $26,$29,116 ; this is the task's sp
stw $27,$29,4 ; this is the task's $1
stw $30,$29,120 ; this is the task's resumption addr
stw $31,$29,124
add $5,$29,$0 ; $5 = pointer to register array
mvfs $4,0 ; $4 = IRQ number
slr $4,$4,16
and $4,$4,0x1F
sll $26,$4,2 ; $26 = 4 * IRQ number
ldw $26,$26,irqsrv ; get addr of service routine
jalr $26 ; call service routine
j resume ; resume task if ISR returns
 
; resume a task
resume:
ldw $29,$0,currentStkTop ; setup kernel mode stack
sub $29,$29,128 ; restore registers
ldw $2,$29,8
ldw $3,$29,12
ldw $4,$29,16
ldw $5,$29,20
ldw $6,$29,24
ldw $7,$29,28
ldw $8,$29,32
ldw $9,$29,36
ldw $10,$29,40
ldw $11,$29,44
ldw $12,$29,48
ldw $13,$29,52
ldw $14,$29,56
ldw $15,$29,60
ldw $16,$29,64
ldw $17,$29,68
ldw $18,$29,72
ldw $19,$29,76
ldw $20,$29,80
ldw $21,$29,84
ldw $22,$29,88
ldw $23,$29,92
ldw $24,$29,96
ldw $25,$29,100
ldw $26,$29,116 ; this is the task's sp
ldw $27,$29,4 ; this is the task's $1
ldw $30,$29,120 ; this is the task's resumption addr
ldw $31,$29,124
add $1,$27,$0 ; $27 -> $1
add $29,$26,$0 ; $26 -> sp
rfx ; return from exception
 
start:
add $8,$0,0xA8003FFF
add $9,$0,0xC0000000
stw $8,$9,0 ; 0xC0000000: j 0xC0010000
stw $8,$9,4 ; 0xC0000004: j 0xC0010004
stw $8,$9,8 ; 0xC0000008: j 0xC0010008
mvfs $8,0
or $8,$8,1 << 27 ; let vector point to RAM
mvts $8,0
add $10,$0,_bdata ; copy data segment
add $8,$0,_edata
sub $9,$8,$10
add $9,$9,_ecode
j cpytest
cpyloop:
ldw $11,$9,0
stw $11,$8,0
cpytest:
sub $8,$8,4
sub $9,$9,4
bgeu $8,$10,cpyloop
add $8,$0,_bbss ; clear bss
add $9,$0,_ebss
j clrtest
clrloop:
stw $0,$8,0
add $8,$8,4
clrtest:
bltu $8,$9,clrloop
ldw $29,$0,task0StkTop ; setup kernel mode stack for task 0
jal main ; call 'main'
start1:
j start1 ; loop
 
enable:
mvfs $8,0
or $8,$8,1 << 23
mvts $8,0
jr $31
 
disable:
mvfs $8,0
and $8,$8,~(1 << 23)
mvts $8,0
jr $31
 
orMask:
mvfs $8,0
and $4,$4,0x0000FFFF ; use lower 16 bits only
or $8,$8,$4
mvts $8,0
jr $31
 
andMask:
mvfs $8,0
or $4,$4,0xFFFF0000 ; use lower 16 bits only
and $8,$8,$4
mvts $8,0
jr $31
 
getISR:
sll $4,$4,2
ldw $2,$4,irqsrv
jr $31
 
setISR:
sll $4,$4,2
stw $5,$4,irqsrv
jr $31
 
startTask:
ldw $29,$0,currentStkTop ; setup kernel mode stack
sub $29,$29,128
stw $0,$29,0 ; preset registers
stw $0,$29,4
stw $0,$29,8
stw $0,$29,12
stw $0,$29,16
stw $0,$29,20
stw $0,$29,24
stw $0,$29,28
stw $0,$29,32
stw $0,$29,36
stw $0,$29,40
stw $0,$29,44
stw $0,$29,48
stw $0,$29,52
stw $0,$29,56
stw $0,$29,60
stw $0,$29,64
stw $0,$29,68
stw $0,$29,72
stw $0,$29,76
stw $0,$29,80
stw $0,$29,84
stw $0,$29,88
stw $0,$29,92
stw $0,$29,96
stw $0,$29,100
stw $0,$29,104
stw $0,$29,108
stw $0,$29,112
add $8,$0,0x80000000
stw $8,$29,116 ; sp
stw $0,$29,120 ; task starts at virtual addr 0
stw $0,$29,124
mvfs $8,0
or $8,$8,1 << 25 ; set previous mode to 'user'
or $8,$8,1 << 22 ; and enable interrupts
mvts $8,0
j resume
 
setTLB:
mvts $4,1 ; set index
mvts $5,2 ; set entryHi
mvts $6,3 ; set entryLo
tbwi ; write TLB entry at index
jr $31
 
.data
 
; interrupt service routine table
 
.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
/os/main.c
0,0 → 1,345
/*
* main.c -- start the ball rolling
*/
 
 
#include "stdarg.h"
#include "start.h"
 
 
/**************************************************************/
 
 
int currentTask;
unsigned int *currentStkTop;
 
 
/**************************************************************/
 
 
unsigned int task0Stack[256];
unsigned int *task0StkTop = task0Stack + 256;
 
 
unsigned char task1Code[] = {
#include "task1.dump"
};
 
unsigned int task1Stack[256];
unsigned int *task1StkTop = task1Stack + 256;
 
 
unsigned char task2Code[] = {
#include "task2.dump"
};
 
unsigned int task2Stack[256];
unsigned int *task2StkTop = task2Stack + 256;
 
 
/**************************************************************/
 
 
void putchar(char c) {
unsigned int *base;
 
if (c == '\n') {
putchar('\r');
}
base = (unsigned int *) 0xF0300000;
while ((*(base + 2) & 1) == 0) ;
*(base + 3) = c;
}
 
 
void puts(char *s) {
char c;
 
while ((c = *s++) != '\0') {
putchar(c);
}
}
 
 
void printn(int n) {
int a;
 
if (n < 0) {
putchar('-');
n = -n;
}
a = n / 10;
if (a != 0) {
printn(a);
}
putchar(n % 10 + '0');
}
 
 
void printu(unsigned int n, unsigned int b) {
unsigned int a;
 
a = n / b;
if (a != 0) {
printu(a, b);
}
putchar("0123456789ABCDEF"[n % b]);
}
 
 
void printf(char *fmt, ...) {
va_list ap;
char c;
int n;
unsigned int u;
char *s;
 
va_start(ap, fmt);
while (1) {
while ((c = *fmt++) != '%') {
if (c == '\0') {
va_end(ap);
return;
}
putchar(c);
}
c = *fmt++;
if (c == 'd') {
n = va_arg(ap, int);
printn(n);
} else
if (c == 'u' || c == 'o' || c == 'x') {
u = va_arg(ap, int);
printu(u, c == 'o' ? 8 : (c == 'x' ? 16 : 10));
} else
if (c == 's') {
s = va_arg(ap, char *);
puts(s);
} else {
putchar(c);
}
}
}
 
 
/**************************************************************/
 
 
static 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",
/* 06 */ "unknown interrupt",
/* 07 */ "unknown interrupt",
/* 08 */ "disk interrupt",
/* 09 */ "unknown interrupt",
/* 10 */ "unknown interrupt",
/* 11 */ "unknown interrupt",
/* 12 */ "unknown interrupt",
/* 13 */ "unknown interrupt",
/* 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",
/* 27 */ "unknown exception",
/* 28 */ "unknown exception",
/* 29 */ "unknown exception",
/* 30 */ "unknown exception",
/* 31 */ "unknown exception"
};
 
 
void defaultISR(int irq, unsigned int *registers) {
printf("\n%s\n", exceptionCause[irq]);
}
 
 
void initInterrupts(void) {
int i;
 
for (i = 0; i < 32; i++) {
setISR(i, defaultISR);
}
}
 
 
/**************************************************************/
 
 
unsigned int getNumber(unsigned char *p) {
return (unsigned int) *(p + 0) << 24 |
(unsigned int) *(p + 1) << 16 |
(unsigned int) *(p + 2) << 8 |
(unsigned int) *(p + 3) << 0;
}
 
 
void loadTask(unsigned char *code,
unsigned int physCodeAddr,
unsigned int physDataAddr) {
unsigned int magic;
unsigned int csize;
unsigned int dsize;
unsigned int bsize;
unsigned char *virtLoadAddr;
int i;
 
magic = getNumber(code);
code += sizeof(unsigned int);
csize = getNumber(code);
code += sizeof(unsigned int);
dsize = getNumber(code);
code += sizeof(unsigned int);
bsize = getNumber(code);
code += sizeof(unsigned int);
if (magic != 0x1AA09232) {
printf("Error: Load module is not executable!\n");
while (1) ;
}
code += 4 * sizeof(unsigned int);
printf("(csize = 0x%x, dsize = 0x%x, bsize = 0x%x)\n",
csize, dsize, bsize);
virtLoadAddr = (unsigned char *) (0xC0000000 | physCodeAddr);
for (i = 0; i < csize; i++) {
*virtLoadAddr++ = *code++;
}
virtLoadAddr = (unsigned char *) (0xC0000000 | physDataAddr);
for (i = 0; i < dsize; i++) {
*virtLoadAddr++ = *code++;
}
for (i = 0; i < bsize; i++) {
*virtLoadAddr++ = '\0';
}
}
 
 
/**************************************************************/
 
 
void trapISR(int irq, unsigned int *registers) {
/* 'putchar' is the only system call yet */
putchar(registers[4]);
/* skip the trap instruction */
registers[30] += 4;
}
 
 
/**************************************************************/
 
 
void missISR(int irq, unsigned int *registers) {
if (currentTask == 1) {
setTLB(5, 0x00000000, 64 << 12 | 0x01); /* code at 256 k */
setTLB(27, 0x00001000, 68 << 12 | 0x03); /* data at 272 k */
setTLB(22, 0x7FFFF000, 80 << 12 | 0x03); /* user-mode stack at 320 k */
} else if (currentTask == 2) {
setTLB(5, 0x00000000, 96 << 12 | 0x01); /* code at 384 k */
setTLB(27, 0x00001000, 100 << 12 | 0x03); /* data at 400 k */
setTLB(22, 0x7FFFF000, 112 << 12 | 0x03); /* user-mode stack at 448 k */
}
}
 
 
void flushTLB(void) {
unsigned int invalPage;
int i;
 
invalPage = 0xC0000000;
for (i = 0; i < 32; i++) {
setTLB(i, invalPage, 0);
invalPage += (1 << 12);
}
}
 
 
/**************************************************************/
 
 
void initTimer(void) {
unsigned int *timerBase;
 
timerBase = (unsigned int *) 0xF0000000;
*(timerBase + 1) = 50000000;
*timerBase = 2;
orMask(1 << 14);
}
 
 
int task1Started = 0;
int task2Started = 0;
 
 
void timerISR(int irq, unsigned int *registers) {
unsigned int *timerBase;
 
timerBase = (unsigned int *) 0xF0000000;
*timerBase = 2;
printf(">|<");
if (currentTask == 0) {
if (!task1Started) {
/* load & start task1 */
printf("\nOS: loading task1\n");
loadTask(task1Code, 64 << 12, 68 << 12);
printf("OS: starting task1\n");
task1Started = 1;
currentTask = 1;
currentStkTop = task1StkTop;
flushTLB();
startTask();
}
} else if (currentTask == 1) {
if (!task2Started) {
/* load & start task2 */
printf("\nOS: loading task2\n");
loadTask(task2Code, 96 << 12, 100 << 12);
printf("OS: starting task2\n");
task2Started = 1;
currentTask = 2;
currentStkTop = task2StkTop;
flushTLB();
startTask();
} else {
/* switch tasks */
currentTask = 2;
currentStkTop = task2StkTop;
flushTLB();
}
} else if (currentTask == 2) {
/* switch tasks */
currentTask = 1;
currentStkTop = task1StkTop;
flushTLB();
}
}
 
 
/**************************************************************/
 
 
void main(void) {
currentTask = 0;
currentStkTop = task0StkTop;
printf("\n");
printf("OS: initializing interrupts\n");
initInterrupts();
setISR(20, trapISR);
setISR(21, missISR);
setISR(14, timerISR);
printf("OS: initializing timer\n");
initTimer();
printf("OS: waiting for interrupt...\n");
enable();
while (1) ;
}
/os/start.h
0,0 → 1,23
/*
* start.h -- startup code
*/
 
 
#ifndef _START_H_
#define _START_H_
 
 
typedef void (*ISR)(int irq, unsigned int *registers);
 
 
void enable(void);
void disable(void);
void orMask(unsigned int mask);
void andMask(unsigned int mask);
ISR getISR(int irq);
void setISR(int irq, ISR isr);
void startTask(void);
void setTLB(int index, unsigned int entryHi, unsigned int entryLo);
 
 
#endif /* _START_H_ */
/os/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:
/os/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_ */
/Makefile
0,0 → 1,38
#
# Makefile for "twotasks-1", a tiny OS which runs two tasks
# (with fixed TLB entries and no page tables)
#
 
BUILD = ../../build
 
.PHONY: all install run clean
 
all: dump/dump task1/task1 task2/task2 os/twotasks-1.bin
 
install: dump/dump task1/task1 task2/task2 os/twotasks-1.bin
mkdir -p $(BUILD)/stdalone
cp os/twotasks-1.bin $(BUILD)/stdalone
cp os/twotasks-1.map $(BUILD)/stdalone
cp os/twotasks-1.exo $(BUILD)/stdalone
 
run: dump/dump task1/task1 task2/task2 os/twotasks-1.bin
$(MAKE) -C os run
 
dump/dump:
$(MAKE) -C dump
 
task1/task1:
$(MAKE) -C task1
 
task2/task2:
$(MAKE) -C task2
 
os/twotasks-1.bin:
$(MAKE) -C os
 
clean:
$(MAKE) -C dump clean
$(MAKE) -C task1 clean
$(MAKE) -C task2 clean
$(MAKE) -C os clean
rm -f *~
/task1/c0.s
0,0 → 1,30
;
; c0.s -- startup code and begin-of-segment labels
;
 
.import main
 
.export _bcode
.export _bdata
.export _bbss
 
.import _ecode
.import _edata
.import _ebss
 
.code
_bcode:
 
.data
_bdata:
 
.bss
_bbss:
 
.code
.align 4
 
start:
jal main ; call 'main' function
stop:
j stop ; just to be sure...
/task1/c1.s
0,0 → 1,19
;
; c1.s -- end-of-segment labels
;
 
.export _ecode
.export _edata
.export _ebss
 
.code
.align 4
_ecode:
 
.data
.align 4
_edata:
 
.bss
.align 4
_ebss:
/task1/task1.c
0,0 → 1,95
/*
* task1.c -- a simple task
*/
 
 
#include "putchar.h"
#include "stdarg.h"
 
 
/**************************************************************/
 
 
void puts(char *s) {
char c;
 
while ((c = *s++) != '\0') {
putchar(c);
}
}
 
 
void printn(int n) {
int a;
 
if (n < 0) {
putchar('-');
n = -n;
}
a = n / 10;
if (a != 0) {
printn(a);
}
putchar(n % 10 + '0');
}
 
 
void printu(unsigned int n, unsigned int b) {
unsigned int a;
 
a = n / b;
if (a != 0) {
printu(a, b);
}
putchar("0123456789ABCDEF"[n % b]);
}
 
 
void printf(char *fmt, ...) {
va_list ap;
char c;
int n;
unsigned int u;
char *s;
 
va_start(ap, fmt);
while (1) {
while ((c = *fmt++) != '%') {
if (c == '\0') {
va_end(ap);
return;
}
putchar(c);
}
c = *fmt++;
if (c == 'd') {
n = va_arg(ap, int);
printn(n);
} else
if (c == 'u' || c == 'o' || c == 'x') {
u = va_arg(ap, int);
printu(u, c == 'o' ? 8 : (c == 'x' ? 16 : 10));
} else
if (c == 's') {
s = va_arg(ap, char *);
puts(s);
} else {
putchar(c);
}
}
}
 
 
/**************************************************************/
 
 
void main(void) {
int i;
 
printf("TASK1: executing...\n");
i = 0;
while (1) {
printf("TASK1: %d\n", i);
i++;
}
}
/task1/putchar.s
0,0 → 1,10
;
; putchar.s -- putchar library function
;
 
.code
.export putchar
 
putchar:
trap
jr $31
/task1/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_ */
/task1/putchar.h
0,0 → 1,13
/*
* putchar.h -- putchar library function
*/
 
 
#ifndef _PUTCHAR_H_
#define _PUTCHAR_H_
 
 
void putchar(char c);
 
 
#endif /* _PUTCHAR_H_ */
/task1/Makefile
0,0 → 1,21
BUILD = ../../../build
 
all: task1
 
task1: c0.o task1.o putchar.o c1.o
$(BUILD)/bin/ld -o task1 c0.o task1.o putchar.o c1.o
 
c0.o: c0.s
$(BUILD)/bin/as -o c0.o c0.s
 
task1.o: task1.c
$(BUILD)/bin/lcc -A -c -o task1.o task1.c
 
putchar.o: putchar.s
$(BUILD)/bin/as -o putchar.o putchar.s
 
c1.o: c1.s
$(BUILD)/bin/as -o c1.o c1.s
 
clean:
rm -f *~ c0.o task1.o putchar.o c1.o task1
/task2/c0.s
0,0 → 1,30
;
; c0.s -- startup code and begin-of-segment labels
;
 
.import main
 
.export _bcode
.export _bdata
.export _bbss
 
.import _ecode
.import _edata
.import _ebss
 
.code
_bcode:
 
.data
_bdata:
 
.bss
_bbss:
 
.code
.align 4
 
start:
jal main ; call 'main' function
stop:
j stop ; just to be sure...
/task2/c1.s
0,0 → 1,19
;
; c1.s -- end-of-segment labels
;
 
.export _ecode
.export _edata
.export _ebss
 
.code
.align 4
_ecode:
 
.data
.align 4
_edata:
 
.bss
.align 4
_ebss:
/task2/task2.c
0,0 → 1,95
/*
* task2.c -- a simple task
*/
 
 
#include "putchar.h"
#include "stdarg.h"
 
 
/**************************************************************/
 
 
void puts(char *s) {
char c;
 
while ((c = *s++) != '\0') {
putchar(c);
}
}
 
 
void printn(int n) {
int a;
 
if (n < 0) {
putchar('-');
n = -n;
}
a = n / 10;
if (a != 0) {
printn(a);
}
putchar(n % 10 + '0');
}
 
 
void printu(unsigned int n, unsigned int b) {
unsigned int a;
 
a = n / b;
if (a != 0) {
printu(a, b);
}
putchar("0123456789ABCDEF"[n % b]);
}
 
 
void printf(char *fmt, ...) {
va_list ap;
char c;
int n;
unsigned int u;
char *s;
 
va_start(ap, fmt);
while (1) {
while ((c = *fmt++) != '%') {
if (c == '\0') {
va_end(ap);
return;
}
putchar(c);
}
c = *fmt++;
if (c == 'd') {
n = va_arg(ap, int);
printn(n);
} else
if (c == 'u' || c == 'o' || c == 'x') {
u = va_arg(ap, int);
printu(u, c == 'o' ? 8 : (c == 'x' ? 16 : 10));
} else
if (c == 's') {
s = va_arg(ap, char *);
puts(s);
} else {
putchar(c);
}
}
}
 
 
/**************************************************************/
 
 
void main(void) {
int i;
 
printf("TASK2: executing...\n");
i = 0;
while (1) {
printf("TASK2: %d\n", i);
i++;
}
}
/task2/putchar.s
0,0 → 1,10
;
; putchar.s -- putchar library function
;
 
.code
.export putchar
 
putchar:
trap
jr $31
/task2/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_ */
/task2/putchar.h
0,0 → 1,13
/*
* putchar.h -- putchar library function
*/
 
 
#ifndef _PUTCHAR_H_
#define _PUTCHAR_H_
 
 
void putchar(char c);
 
 
#endif /* _PUTCHAR_H_ */
/task2/Makefile
0,0 → 1,21
BUILD = ../../../build
 
all: task2
 
task2: c0.o task2.o putchar.o c1.o
$(BUILD)/bin/ld -o task2 c0.o task2.o putchar.o c1.o
 
c0.o: c0.s
$(BUILD)/bin/as -o c0.o c0.s
 
task2.o: task2.c
$(BUILD)/bin/lcc -A -c -o task2.o task2.c
 
putchar.o: putchar.s
$(BUILD)/bin/as -o putchar.o putchar.s
 
c1.o: c1.s
$(BUILD)/bin/as -o c1.o c1.s
 
clean:
rm -f *~ c0.o task2.o putchar.o c1.o task2

powered by: WebSVN 2.1.0

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