Compare commits
68 Commits
gpanel-dri
...
uecide-too
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
427487850c | ||
|
|
a0c256c1f0 | ||
|
|
9d8ad7ccf5 | ||
|
|
a5d7f4ea99 | ||
|
|
435d3c34cf | ||
|
|
0e39621fea | ||
|
|
7477abe7f3 | ||
|
|
7075769d7c | ||
|
|
f5452b74de | ||
|
|
f3dbdc7615 | ||
|
|
66e5cd88c0 | ||
|
|
0583055d00 | ||
|
|
aea2050c49 | ||
|
|
5fde14ecea | ||
|
|
ca67f33a30 | ||
|
|
20238b7208 | ||
|
|
1a7125b892 | ||
|
|
d048ee200e | ||
|
|
6ddcb56e2a | ||
|
|
148bb1cac6 | ||
|
|
b2bde490b4 | ||
|
|
e1d3583dcd | ||
|
|
21f8d60095 | ||
|
|
6457d878c0 | ||
|
|
e5c844eff2 | ||
|
|
4e90456341 | ||
|
|
bfc3125556 | ||
|
|
fa094d1744 | ||
|
|
b7a3d6f665 | ||
|
|
fb05f20fbe | ||
|
|
e050ac6ee6 | ||
|
|
8dd0fb4860 | ||
|
|
6028db705a | ||
|
|
6d501bfc7c | ||
|
|
09205046a4 | ||
|
|
ac9ef0eee9 | ||
|
|
e073fcbd64 | ||
|
|
0507073b60 | ||
|
|
76cb491c09 | ||
|
|
f3f28ceca5 | ||
|
|
e3c86f0ffa | ||
|
|
7503ce7856 | ||
|
|
1a1daf15a3 | ||
|
|
a40bcee878 | ||
|
|
e67e939fb9 | ||
|
|
9027547fa6 | ||
|
|
7c2aa43862 | ||
|
|
8988b8b013 | ||
|
|
d2940a8719 | ||
|
|
be1726a662 | ||
|
|
2fd36d9175 | ||
|
|
6f0a48330c | ||
|
|
4dd9308e25 | ||
|
|
98f3efcb70 | ||
|
|
2e716e099c | ||
|
|
03ed62db5d | ||
|
|
c46bd3c1e9 | ||
|
|
a673c028f8 | ||
|
|
7ddf7686a3 | ||
|
|
abcfb06b0b | ||
|
|
e00196ee21 | ||
|
|
5b04c6b168 | ||
|
|
7f69510488 | ||
|
|
058b6c4de0 | ||
|
|
1e4005cc4b | ||
|
|
66a7727085 | ||
|
|
2bfd3df2a6 | ||
|
|
162f0d34b5 |
@@ -4,16 +4,16 @@
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
double fabs(), floor(), ceil(), fmod(), ldexp();
|
||||
double sqrt(), hypot(), atof();
|
||||
double sin(), cos(), tan(), asin(), acos(), atan(), atan2();
|
||||
double exp(), log(), log10(), pow();
|
||||
double sinh(), cosh(), tanh();
|
||||
double gamma();
|
||||
double j0(), j1(), jn(), y0(), y1(), yn();
|
||||
double fabs(double), floor(double), ceil(double);
|
||||
double sqrt(double), hypot(double, double);
|
||||
double sin(double), cos(double), tan(double);
|
||||
double asin(double), acos(double), atan(double), atan2(double, double);
|
||||
double exp(double), log(double), log10(double), pow(double, double);
|
||||
double sinh(double), cosh(double), tanh(double);
|
||||
double j0(double), j1(double), jn(int, double);
|
||||
double y0(double), y1(double), yn(int, double);
|
||||
|
||||
#define HUGE 1.701411733192644270e38
|
||||
#define LOGHUGE 39
|
||||
#define HUGE_VAL 3.40282347e+38 /* TBD??? use infinity? */
|
||||
|
||||
int isnanf(float x);
|
||||
int isnan(double x);
|
||||
|
||||
@@ -96,12 +96,10 @@ long random (void);
|
||||
char *setstate (char *);
|
||||
void srandom (unsigned);
|
||||
|
||||
#ifndef __SMALLER_C__
|
||||
double atof (const char *);
|
||||
double strtod (const char *, char **);
|
||||
char *ecvt (double, int, int *, int *);
|
||||
char *fcvt (double, int, int *, int *);
|
||||
char *gcvt (double, int, char *);
|
||||
#endif
|
||||
|
||||
#endif /* _STDLIB_H_ */
|
||||
|
||||
@@ -2,7 +2,7 @@ TOPSRC = $(shell cd ..; pwd)
|
||||
SUBDIR = startup libc libm libcurses libtermlib libwiznet libreadline libgpanel
|
||||
PROG = ar as aout ld nm ranlib size strip
|
||||
|
||||
CFLAGS += -std=gnu89 -fno-builtin -g -Werror -Wall -DCROSS -I. \
|
||||
CFLAGS = -Os -std=gnu89 -fno-builtin -g -Werror -Wall -DCROSS -I. \
|
||||
-idirafter $(TOPSRC)/include \
|
||||
-idirafter $(TOPSRC)/src/cmd/ar \
|
||||
-idirafter $(TOPSRC)/src/cmd/as
|
||||
|
||||
@@ -8,7 +8,7 @@ vpath %.c $(LIBCDIR)/mips/sys $(LIBCDIR)/gen $(LIBCDIR)/stdio \
|
||||
$(LIBCDIR)/stdlib $(LIBCDIR)/string $(LIBCDIR)/inet \
|
||||
$(LIBCDIR)/compat $(LIBCDIR)/runtime
|
||||
|
||||
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
ASFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -I$(LIBCDIR)/mips/sys
|
||||
|
||||
# modules which can not use SYSCALL and must be assembled from sources. The
|
||||
@@ -95,7 +95,8 @@ OBJS += creat.o ftime.o gethostid.o memccpy.o memchr.o \
|
||||
|
||||
# libc/runtime
|
||||
OBJS += addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \
|
||||
mulsf3.o negsf2.o subsf3.o sc_case.o
|
||||
mulsf3.o negsf2.o subsf3.o sc_case.o fixunssfsi.o \
|
||||
floatunsisf.o
|
||||
|
||||
all: ../libc.a
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
||||
|
||||
vpath %.c $(TOPSRC)/src/libcurses
|
||||
|
||||
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
|
||||
OBJS = addch.o addstr.o box.o clear.o clrtobot.o clrtoeol.o cr_put.o \
|
||||
cr_tty.o curses.o delch.o deleteln.o delwin.o endwin.o erase.o \
|
||||
|
||||
@@ -3,10 +3,10 @@ include $(TOPSRC)/target.mk
|
||||
|
||||
vpath %.c $(TOPSRC)/src/libgpanel
|
||||
|
||||
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
|
||||
OBJS = open.o clear.o pixel.o line.o rect.o fill.o circle.o \
|
||||
image.o char.o text.o text_width.o
|
||||
OBJS = open.o clear.o pixel.o line.o rect.o fill.o fill_triangle.o \
|
||||
circle.o image.o char.o text.o text_width.o
|
||||
|
||||
all: ../libgpanel.a
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
||||
|
||||
vpath %.c $(TOPSRC)/src/libm
|
||||
|
||||
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
|
||||
OBJS = asin.o atan.o exp.o erf.o floor.o fmod.o hypot.o j0.o j1.o \
|
||||
jn.o log.o pow.o sin.o sinh.o sqrt.o tan.o tanh.o
|
||||
|
||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
||||
|
||||
vpath %.c $(TOPSRC)/src/libreadline
|
||||
|
||||
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
|
||||
OBJS = readline.o
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
||||
|
||||
vpath %.c $(TOPSRC)/src/libtermlib
|
||||
|
||||
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
|
||||
OBJS = termcap.o tgoto.o tputs.o tcattr.o
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
||||
|
||||
vpath %.c $(TOPSRC)/src/libwiznet
|
||||
|
||||
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
|
||||
|
||||
OBJS = w5100.o socket.o ethernet.o client.o server.o udp.o
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ TOPSRC = $(shell cd ../..; pwd)
|
||||
include $(TOPSRC)/target.mk
|
||||
vpath %.c $(TOPSRC)/src/startup-mips
|
||||
|
||||
CFLAGS = -B$(TOPSRC)/lib/ -O -Wa,-x $(DEFS)
|
||||
CFLAGS = -Os -B$(TOPSRC)/lib/ -Wa,-x $(DEFS)
|
||||
|
||||
OBJS = ../crt0.o
|
||||
|
||||
|
||||
@@ -605,6 +605,7 @@ file /bin/whoami
|
||||
file /bin/write
|
||||
mode 02755
|
||||
file /bin/xargs
|
||||
file /bin/yacc
|
||||
file /bin/zcat
|
||||
|
||||
link /bin/[
|
||||
@@ -671,6 +672,7 @@ default
|
||||
filemode 0775
|
||||
dir /games
|
||||
file /games/adventure
|
||||
file /games/aclock
|
||||
file /games/arithmetic
|
||||
file /games/atc
|
||||
file /games/backgammon
|
||||
@@ -1116,6 +1118,7 @@ file /share/examples/gpanel/Makefile
|
||||
file /share/examples/gpanel/circle.c
|
||||
file /share/examples/gpanel/color.c
|
||||
file /share/examples/gpanel/fill.c
|
||||
file /share/examples/gpanel/flappy.c
|
||||
file /share/examples/gpanel/font.c
|
||||
file /share/examples/gpanel/line.c
|
||||
file /share/examples/gpanel/pixel.c
|
||||
@@ -1129,6 +1132,7 @@ file /share/examples/gpanel/fonts/digits20.c
|
||||
file /share/examples/gpanel/fonts/digits32.c
|
||||
file /share/examples/gpanel/fonts/lucidasans11.c
|
||||
file /share/examples/gpanel/fonts/lucidasans15.c
|
||||
file /share/examples/gpanel/fonts/lucidasans28.c
|
||||
file /share/examples/gpanel/fonts/lucidasans7.c
|
||||
file /share/examples/gpanel/fonts/lucidasans9.c
|
||||
file /share/examples/gpanel/fonts/verdana7.c
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
CC = cc
|
||||
LIBS = -lgpanel
|
||||
PROG = tft tftetris pixel line rect fill circle font color speed
|
||||
PROG = tft tftetris pixel line rect fill circle font color speed flappy
|
||||
|
||||
FONTS = 5x7.o 6x9.o digits20.o digits32.o lucidasans11.o lucidasans15.o \
|
||||
lucidasans7.o lucidasans9.o verdana7.o
|
||||
lucidasans28.o lucidasans7.o lucidasans9.o verdana7.o
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
@@ -37,6 +37,9 @@ color: color.c
|
||||
speed: speed.c lucidasans15.o
|
||||
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) speed.c lucidasans15.o $(LIBS)
|
||||
|
||||
flappy: flappy.c lucidasans15.o lucidasans28.o
|
||||
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) flappy.c lucidasans15.o lucidasans28.o $(LIBS)
|
||||
|
||||
font: font.c $(FONTS)
|
||||
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) font.c $(FONTS) $(LIBS)
|
||||
|
||||
@@ -58,6 +61,9 @@ lucidasans11.o: fonts/lucidasans11.c
|
||||
lucidasans15.o: fonts/lucidasans15.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $?
|
||||
|
||||
lucidasans28.o: fonts/lucidasans28.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $?
|
||||
|
||||
lucidasans7.o: fonts/lucidasans7.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $?
|
||||
|
||||
|
||||
439
share/examples/gpanel/flappy.c
Normal file
439
share/examples/gpanel/flappy.c
Normal file
@@ -0,0 +1,439 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sgtty.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/gpanel.h>
|
||||
|
||||
/*
|
||||
* Assign human-readable names to some common 16-bit color values:
|
||||
*/
|
||||
#define BLACK 0x0000
|
||||
#define BLUE 0x002F
|
||||
#define RED 0xF800
|
||||
#define GREEN 0x07E0
|
||||
#define CYAN 0x07FF
|
||||
#define MAGENTA 0xF81F
|
||||
#define YELLOW 0xFFE0
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
/*
|
||||
* Redraw every 50 msec
|
||||
*/
|
||||
#define DRAW_LOOP_INTERVAL 50
|
||||
|
||||
/*
|
||||
* File name for saving the high score.
|
||||
*/
|
||||
#define SCORE_FILENAME "flappy.score"
|
||||
|
||||
/*
|
||||
* Data from external font files.
|
||||
*/
|
||||
extern const struct gpanel_font_t font_lucidasans15;
|
||||
extern const struct gpanel_font_t font_lucidasans28;
|
||||
|
||||
int wing;
|
||||
int fx, fy, fall_rate;
|
||||
int pillar_pos, gap_pos;
|
||||
int score;
|
||||
int high_score = 0;
|
||||
int running = 0;
|
||||
int crashed = 0;
|
||||
int scr_press = 0;
|
||||
time_t next_draw_time;
|
||||
|
||||
void rect(int color, int x, int y, int w, int h)
|
||||
{
|
||||
gpanel_rect(color, x, y, x+w-1, y+h-1);
|
||||
}
|
||||
|
||||
void fill(int color, int x, int y, int w, int h)
|
||||
{
|
||||
gpanel_fill(color, x, y, x+w-1, y+h-1);
|
||||
}
|
||||
|
||||
void draw_pillar(int x, int gap)
|
||||
{
|
||||
if (x >= 320)
|
||||
return;
|
||||
|
||||
fill(GREEN, x+2, 2, 46, gap-4);
|
||||
fill(GREEN, x+2, gap+92, 46, 136-gap);
|
||||
|
||||
rect(BLACK, x, 0, 50, gap);
|
||||
rect(BLACK, x+1, 1, 48, gap-2);
|
||||
rect(BLACK, x, gap+90, 50, 140-gap);
|
||||
rect(BLACK, x+1, gap+91, 48, 138-gap);
|
||||
}
|
||||
|
||||
void clear_pillar(int x, int gap)
|
||||
{
|
||||
if (x >= 320)
|
||||
return;
|
||||
|
||||
/* "Cheat" slightly and just clear the right hand pixels
|
||||
* to help minimise flicker, the rest will be overdrawn. */
|
||||
fill(BLUE, x+45, 0, 5, gap);
|
||||
fill(BLUE, x+45, gap+90, 5, 140-gap);
|
||||
}
|
||||
|
||||
void clear_flappy(int x, int y)
|
||||
{
|
||||
fill(BLUE, x, y, 34, 24);
|
||||
}
|
||||
|
||||
void draw_flappy(int x, int y)
|
||||
{
|
||||
/* Upper & lower body */
|
||||
fill(BLACK, x+2, y+8, 2, 10);
|
||||
fill(BLACK, x+4, y+6, 2, 2);
|
||||
fill(BLACK, x+6, y+4, 2, 2);
|
||||
fill(BLACK, x+8, y+2, 4, 2);
|
||||
fill(BLACK, x+12, y, 12, 2);
|
||||
fill(BLACK, x+24, y+2, 2, 2);
|
||||
fill(BLACK, x+26, y+4, 2, 2);
|
||||
fill(BLACK, x+28, y+6, 2, 6);
|
||||
fill(BLACK, x+10, y+22, 10, 2);
|
||||
fill(BLACK, x+4, y+18, 2, 2);
|
||||
fill(BLACK, x+6, y+20, 4, 2);
|
||||
|
||||
/* Body fill */
|
||||
fill(YELLOW, x+12, y+2, 6, 2);
|
||||
fill(YELLOW, x+8, y+4, 8, 2);
|
||||
fill(YELLOW, x+6, y+6, 10, 2);
|
||||
fill(YELLOW, x+4, y+8, 12, 2);
|
||||
fill(YELLOW, x+4, y+10, 14, 2);
|
||||
fill(YELLOW, x+4, y+12, 16, 2);
|
||||
fill(YELLOW, x+4, y+14, 14, 2);
|
||||
fill(YELLOW, x+4, y+16, 12, 2);
|
||||
fill(YELLOW, x+6, y+18, 12, 2);
|
||||
fill(YELLOW, x+10, y+20, 10, 2);
|
||||
|
||||
/* Eye */
|
||||
fill(BLACK, x+18, y+2, 2, 2);
|
||||
fill(BLACK, x+16, y+4, 2, 6);
|
||||
fill(BLACK, x+18, y+10, 2, 2);
|
||||
fill(WHITE, x+18, y+4, 2, 6);
|
||||
fill(WHITE, x+20, y+2, 4, 10);
|
||||
fill(WHITE, x+24, y+4, 2, 8);
|
||||
fill(WHITE, x+26, y+6, 2, 6);
|
||||
fill(BLACK, x+24, y+6, 2, 4);
|
||||
|
||||
/* Beak */
|
||||
fill(BLACK, x+20, y+12, 12, 2);
|
||||
fill(BLACK, x+18, y+14, 2, 2);
|
||||
fill(RED, x+20, y+14, 12, 2);
|
||||
fill(BLACK, x+32, y+14, 2, 2);
|
||||
fill(BLACK, x+16, y+16, 2, 2);
|
||||
fill(RED, x+18, y+16, 2, 2);
|
||||
fill(BLACK, x+20, y+16, 12, 2);
|
||||
fill(BLACK, x+18, y+18, 2, 2);
|
||||
fill(RED, x+20, y+18, 10, 2);
|
||||
fill(BLACK, x+30, y+18, 2, 2);
|
||||
fill(BLACK, x+20, y+20, 10, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wing down.
|
||||
*/
|
||||
void draw_wing1(int x, int y)
|
||||
{
|
||||
fill(BLACK, x, y+14, 2, 6);
|
||||
fill(BLACK, x+2, y+20, 8, 2);
|
||||
fill(BLACK, x+2, y+12, 10, 2);
|
||||
fill(BLACK, x+12, y+14, 2, 2);
|
||||
fill(BLACK, x+10, y+16, 2, 2);
|
||||
fill(WHITE, x+2, y+14, 8, 6);
|
||||
fill(BLACK, x+8, y+18, 2, 2);
|
||||
fill(WHITE, x+10, y+14, 2, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wing middle.
|
||||
*/
|
||||
void draw_wing2(int x, int y)
|
||||
{
|
||||
fill(BLACK, x+2, y+10, 10, 2);
|
||||
fill(BLACK, x+2, y+16, 10, 2);
|
||||
fill(BLACK, x, y+12, 2, 4);
|
||||
fill(BLACK, x+12, y+12, 2, 4);
|
||||
fill(WHITE, x+2, y+12, 10, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wing up.
|
||||
*/
|
||||
void draw_wing3(int x, int y)
|
||||
{
|
||||
fill(BLACK, x+2, y+6, 8, 2);
|
||||
fill(BLACK, x, y+8, 2, 6);
|
||||
fill(BLACK, x+10, y+8, 2, 2);
|
||||
fill(BLACK, x+12, y+10, 2, 4);
|
||||
fill(BLACK, x+10, y+14, 2, 2);
|
||||
fill(BLACK, x+2, y+14, 2, 2);
|
||||
fill(BLACK, x+4, y+16, 6, 2);
|
||||
fill(WHITE, x+2, y+8, 8, 6);
|
||||
fill(WHITE, x+4, y+14, 6, 2);
|
||||
fill(WHITE, x+10, y+10, 2, 4);
|
||||
}
|
||||
|
||||
time_t millis()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void start_game()
|
||||
{
|
||||
fx = 50;
|
||||
fy = 125;
|
||||
fall_rate = -1;
|
||||
pillar_pos = 320;
|
||||
gap_pos = 60;
|
||||
crashed = 0;
|
||||
score = 0;
|
||||
|
||||
gpanel_clear(BLUE, 0, 0);
|
||||
gpanel_text(&font_lucidasans28, WHITE, BLUE, 10, 10,
|
||||
"Flappy Bird");
|
||||
gpanel_text(&font_lucidasans15, WHITE, BLUE, 50, 180,
|
||||
"(Press Space to start)");
|
||||
|
||||
char score_line[80];
|
||||
sprintf(score_line, "High Score: %u", high_score);
|
||||
gpanel_text(&font_lucidasans28, GREEN, BLUE, 10, 60, score_line);
|
||||
|
||||
/* Draw ground. */
|
||||
int tx, ty = 230;
|
||||
for (tx = 0; tx <= 300; tx += 20) {
|
||||
gpanel_fill_triangle(GREEN, tx, ty, tx+9, ty, tx, ty+9);
|
||||
gpanel_fill_triangle(YELLOW, tx+9, ty+9, tx+9, ty, tx, ty+9);
|
||||
gpanel_fill_triangle(YELLOW, tx+10, ty, tx+19, ty, tx+10, ty+9);
|
||||
gpanel_fill_triangle(GREEN, tx+19, ty+9, tx+19, ty, tx+10, ty+9);
|
||||
}
|
||||
|
||||
next_draw_time = millis() + DRAW_LOOP_INTERVAL;
|
||||
}
|
||||
|
||||
void draw_loop()
|
||||
{
|
||||
/* Clear moving items. */
|
||||
clear_pillar(pillar_pos, gap_pos);
|
||||
|
||||
/* Move items. */
|
||||
if (running) {
|
||||
clear_flappy(fx, fy);
|
||||
|
||||
fy += fall_rate;
|
||||
fall_rate++;
|
||||
|
||||
pillar_pos -= 5;
|
||||
if (pillar_pos == 0) {
|
||||
score++;
|
||||
}
|
||||
else if (pillar_pos < -50) {
|
||||
pillar_pos = 320;
|
||||
gap_pos = 20 + random() % 100;
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw moving items & animate. */
|
||||
draw_flappy(fx, fy);
|
||||
draw_pillar(pillar_pos, gap_pos);
|
||||
switch (wing) {
|
||||
case 0:
|
||||
case 1:
|
||||
draw_wing1(fx, fy);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
draw_wing2(fx, fy);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
draw_wing3(fx, fy);
|
||||
break;
|
||||
}
|
||||
wing++;
|
||||
if (wing == 6)
|
||||
wing = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write high score value to file.
|
||||
*/
|
||||
void save_score()
|
||||
{
|
||||
int fd, nbytes;
|
||||
char line[80];
|
||||
|
||||
fd = open(SCORE_FILENAME, O_WRONLY | O_CREAT, 0644);
|
||||
if (fd < 0) {
|
||||
perror(SCORE_FILENAME);
|
||||
return;
|
||||
}
|
||||
sprintf(line, "%u\n", high_score);
|
||||
nbytes = strlen(line);
|
||||
if (write(fd, line, nbytes) != nbytes)
|
||||
perror(SCORE_FILENAME);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read high score value from file.
|
||||
*/
|
||||
void load_score()
|
||||
{
|
||||
int fd, nbytes;
|
||||
char line[80];
|
||||
|
||||
fd = open(SCORE_FILENAME, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
/* No high score file yet. */
|
||||
return;
|
||||
}
|
||||
nbytes = read(fd, line, sizeof(line));
|
||||
if (nbytes <= 0) {
|
||||
if (nbytes < 0)
|
||||
perror(SCORE_FILENAME);
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
high_score = strtol(line, 0, 0);
|
||||
}
|
||||
|
||||
void check_collision()
|
||||
{
|
||||
/* Collision with ground. */
|
||||
if (fy > 206)
|
||||
crashed = 1;
|
||||
|
||||
/* Collision with pillar. */
|
||||
if (fx + 34 > pillar_pos && fx < pillar_pos + 50)
|
||||
if (fy < gap_pos || fy + 24 > gap_pos + 90)
|
||||
crashed = 1;
|
||||
|
||||
if (crashed) {
|
||||
gpanel_text(&font_lucidasans28, RED, BLUE, 50, 50, "Game Over!");
|
||||
|
||||
char score_line[80];
|
||||
sprintf(score_line, "Score: %u", score);
|
||||
gpanel_text(&font_lucidasans28, RED, BLUE, 50, 100, score_line);
|
||||
|
||||
if (score > high_score) {
|
||||
high_score = score;
|
||||
gpanel_text(&font_lucidasans28, RED, BLUE, 50, 150, "NEW HIGH!");
|
||||
save_score();
|
||||
}
|
||||
|
||||
/* Stop animation. */
|
||||
running = 0;
|
||||
|
||||
/* Delay to stop any last minute clicks from restarting immediately. */
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
#ifndef SDL
|
||||
struct sgttyb origtty, newtty;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Terminate the game when ^C pressed.
|
||||
*/
|
||||
void quit(int sig)
|
||||
{
|
||||
signal(SIGINT, SIG_IGN);
|
||||
#ifndef SDL
|
||||
if (newtty.sg_flags != 0)
|
||||
ioctl(0, TIOCSETP, &origtty);
|
||||
#endif
|
||||
gpanel_close();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 1 when any key is pressed on console.
|
||||
*/
|
||||
int get_input()
|
||||
{
|
||||
#ifdef SDL
|
||||
extern int gpanel_input(void);
|
||||
|
||||
return gpanel_input();
|
||||
#else
|
||||
if (newtty.sg_flags == 0) {
|
||||
ioctl(0, TIOCGETP, &origtty);
|
||||
|
||||
newtty = origtty;
|
||||
newtty.sg_flags &= ~(ECHO|XTABS);
|
||||
newtty.sg_flags |= CBREAK;
|
||||
ioctl(0, TIOCSETP, &newtty);
|
||||
}
|
||||
int nchars = 0;
|
||||
ioctl(0, FIONREAD, &nchars);
|
||||
if (nchars <= 0)
|
||||
return 0;
|
||||
|
||||
char c;
|
||||
read(0, &c, 1);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
char *devname = "/dev/tft0";
|
||||
int xsize = 320, ysize = 240;
|
||||
|
||||
signal(SIGINT, quit);
|
||||
if (gpanel_open(devname) < 0) {
|
||||
printf("Cannot open %s\n", devname);
|
||||
exit(-1);
|
||||
}
|
||||
gpanel_clear(BLUE, &xsize, &ysize);
|
||||
|
||||
load_score();
|
||||
start_game();
|
||||
|
||||
for (;;) {
|
||||
if (millis() > next_draw_time && !crashed) {
|
||||
draw_loop();
|
||||
check_collision();
|
||||
next_draw_time += DRAW_LOOP_INTERVAL;
|
||||
}
|
||||
usleep(10000);
|
||||
|
||||
/* Get user input. */
|
||||
int user_input = get_input();
|
||||
|
||||
/* Process "user input". */
|
||||
if (user_input > 0 && !scr_press) {
|
||||
if (crashed) {
|
||||
/* Restart game. */
|
||||
start_game();
|
||||
}
|
||||
else if (!running) {
|
||||
/* Clear text & start scrolling. */
|
||||
gpanel_fill(BLUE, 0, 0, 320-1, 100);
|
||||
gpanel_fill(BLUE, 0, 180, 320-1, 205);
|
||||
running = 1;
|
||||
} else {
|
||||
/* Fly up. */
|
||||
fall_rate = -8;
|
||||
scr_press = 1;
|
||||
}
|
||||
} else if (user_input == 0 && scr_press) {
|
||||
/* Attempt to throttle presses. */
|
||||
scr_press = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
CFLAGS = -Wall -O -g
|
||||
LDFLAGS = -lpng
|
||||
LDFLAGS = -L/opt/local/lib -lpng
|
||||
|
||||
FONTS = digits32.c \
|
||||
digits20.c \
|
||||
@@ -47,6 +47,11 @@ lucidasans15.c: convbdf ttf/Lucida_Sans_Unicode.ttf
|
||||
./convbdf -u164 -a5 -d5 lucidasans15.bdf
|
||||
rm -f lucidasans15.bdf
|
||||
|
||||
lucidasans28.c: convbdf ttf/Lucida_Sans_Unicode.ttf
|
||||
-otf2bdf -p 28 -l "$(CHARSET)" ttf/Lucida_Sans_Unicode.ttf > lucidasans28.bdf
|
||||
./convbdf -u164 -a11 -d9 lucidasans28.bdf
|
||||
rm -f lucidasans28.bdf
|
||||
|
||||
lucidasans9.c: convbdf ttf/Lucida_Sans_Unicode.ttf
|
||||
-otf2bdf -p 9 -l "$(CHARSET)" ttf/Lucida_Sans_Unicode.ttf > lucidasans9.bdf
|
||||
./convbdf -u164 -a2 -d3 lucidasans9.bdf
|
||||
|
||||
8277
share/examples/gpanel/fonts/lucidasans28.c
Normal file
8277
share/examples/gpanel/fonts/lucidasans28.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,8 @@ SUBDIR = adb adc-demo aout ar as awk basic calendar cc chflags \
|
||||
man md5 med more nm passwd pdc picoc portio printf pwm \
|
||||
ranlib re renice retroforth scm sed setty sh sl smallc \
|
||||
smlrc smux stty sysctl test uname wiznet xargs \
|
||||
zmodem gtest msec unixbench cron compress date2 tip \
|
||||
talloc uucp
|
||||
zmodem gtest msec cron compress date2 tip \
|
||||
talloc uucp yacc
|
||||
|
||||
# /sbin
|
||||
SUBDIR += chown chroot disktool fsck getty init \
|
||||
|
||||
@@ -91,6 +91,7 @@ exform(fcount, ifp, itype, ptype)
|
||||
struct {
|
||||
long sa;
|
||||
int sb, sc;
|
||||
double sd; /* assume double = float = 32 bits */
|
||||
} fw;
|
||||
|
||||
while (fcount > 0) {
|
||||
@@ -225,18 +226,20 @@ exform(fcount, ifp, itype, ptype)
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
*(double *)&fw = 0.0;
|
||||
case 'F':
|
||||
fw.sd = 0.0;
|
||||
fw.sa = wx;
|
||||
print("%-16.9f", *(double *)&fw);
|
||||
print("%-16.9f", fw.sd);
|
||||
dotinc = 4;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
/* 64-bit double not supported */
|
||||
case 'F':
|
||||
fw.sa = wx;
|
||||
print("%-32.18F", *(double *)&fw);
|
||||
dotinc = 8;
|
||||
break;
|
||||
|
||||
#endif
|
||||
case 'n': case 'N':
|
||||
printc('\n');
|
||||
dotinc = 0;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <time.h>
|
||||
# include <errno.h>
|
||||
# include <getopt.h>
|
||||
#else
|
||||
|
||||
@@ -97,7 +97,7 @@ typedef struct {
|
||||
/* Header structure internal format. */
|
||||
typedef struct {
|
||||
off_t size; /* size of the object in bytes */
|
||||
long date; /* date */
|
||||
time_t date; /* date */
|
||||
int lname; /* size of the long name in bytes */
|
||||
int gid; /* group */
|
||||
int uid; /* owner */
|
||||
|
||||
@@ -91,7 +91,8 @@ delete(argv)
|
||||
SETCF(tfd, tname, afd, archive, NOPAD);
|
||||
copy_ar(&cf, size);
|
||||
(void)close(tfd);
|
||||
(void)ftruncate(afd, size + SARMAG);
|
||||
if (ftruncate(afd, size + SARMAG) < 0)
|
||||
/* ignore */;
|
||||
close_archive(afd);
|
||||
|
||||
if (*argv) {
|
||||
|
||||
@@ -136,7 +136,8 @@ move(argv)
|
||||
cf.rfd = tfd3;
|
||||
copy_ar(&cf, size);
|
||||
|
||||
(void)ftruncate(afd, tsize + SARMAG);
|
||||
if (ftruncate(afd, tsize + SARMAG) < 0)
|
||||
/* ignore */;
|
||||
close_archive(afd);
|
||||
|
||||
if (*argv) {
|
||||
|
||||
@@ -190,7 +190,8 @@ append: while ((file = *argv++) != 0) {
|
||||
cf.rfd = tfd2;
|
||||
copy_ar(&cf, size);
|
||||
|
||||
(void)ftruncate(afd, tsize + SARMAG);
|
||||
if (ftruncate(afd, tsize + SARMAG) < 0)
|
||||
/* ignore */;
|
||||
close_archive(afd);
|
||||
return(err);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
* only. IE: A is equivalent to A0 ... Z$ is equivalent to Z0$
|
||||
*
|
||||
* Statements:
|
||||
* BEEP freq,ms - Generate a BEEP on the PC speaker
|
||||
* CLEAR - Erase variables only
|
||||
* CLOSE#n - Close file (0-9) opened with OPEN
|
||||
* DATA - Enter "inline" data statements
|
||||
@@ -155,7 +154,7 @@
|
||||
#define SAVE 25
|
||||
#define LOAD 26
|
||||
#define DELAY 27
|
||||
#define BEEP 28
|
||||
//#define BEEP 28
|
||||
#define DOS 29
|
||||
#define OUT 30
|
||||
|
||||
@@ -279,11 +278,6 @@ int eval_sub(void);
|
||||
|
||||
WINDOW *win;
|
||||
|
||||
void beep (int i, int t)
|
||||
{
|
||||
printf("BEEP not implemented yet, at line %u\n", line);
|
||||
}
|
||||
|
||||
void delay (int msec)
|
||||
{
|
||||
usleep (msec * 1000);
|
||||
@@ -1371,11 +1365,6 @@ input: if (ii == -1)
|
||||
case SRND:
|
||||
srandom(eval_num());
|
||||
break;
|
||||
case BEEP:
|
||||
i = eval_num();
|
||||
expect(',');
|
||||
beep(i, eval_num());
|
||||
break;
|
||||
case DOS:
|
||||
eval_char();
|
||||
fflush(stdout);
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
December 17, 2015 : emg 2.0
|
||||
---------------------------
|
||||
Remove several unused functions.
|
||||
Greatly simplify the buffer logic. emg no longer has multi-buffer support.
|
||||
Remember to reset line number when opening files.
|
||||
|
||||
August 21, 2015 : emg 1.9
|
||||
-------------------------
|
||||
Smarter terminal setup.
|
||||
Clarify quit message if you haven't saved the file.
|
||||
Remove non-standard M-Z quick save.
|
||||
Simpler arrow key and PgUp/PgDn logic.
|
||||
|
||||
August 10, 2015 : emg 1.8
|
||||
-------------------------
|
||||
Remove most buffer functions.
|
||||
Remove all window functions.
|
||||
Remove window.c, the one remaining function goes to display.c
|
||||
Rework the modeline to look like Mg.
|
||||
Add a version function, bound to "M-e".
|
||||
Add a version function, bound to "M-E".
|
||||
|
||||
July 10, 2014 : emg 1.7
|
||||
-----------------------
|
||||
|
||||
@@ -13,11 +13,6 @@ CFLAGS += -ffunction-sections -fdata-sections
|
||||
# This reduces code size significantly.
|
||||
CFLAGS += -mips16
|
||||
|
||||
# Set the screen size.
|
||||
# Will default to COLS=80 and ROWS=24
|
||||
# if not set here.
|
||||
#CFLAGS += -DCOLS=80 -DROWS=24
|
||||
|
||||
# with CFLAGS+= -ffunction-sections -fdata-sections
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
emg
|
||||
===
|
||||
|
||||
emg, or Ersatz Mg, is a very tiny Emacs-like text editor created by
|
||||
combining elements of Ersatz Emacs and Mg (both the mg1a release and the
|
||||
current OpenBSD-maintained version).
|
||||
|
||||
The goal of this editor is to have something Emacs like for RetroBSD
|
||||
(a release of 2.11BSD for PIC32 microcontrollers). After noticing that the
|
||||
vi clone RetroBSD is using, VIrus, is GPL-licensed, I decided to provide
|
||||
a better-licensed editor. I also decided that, as a vi user myself, it would
|
||||
be easier to create an Emacs clone. Like you, I'm also unsure as to how that
|
||||
conclusion was reached.
|
||||
|
||||
I had initially tried to port Mg to RetroBSD but it was simply too large.
|
||||
Ersatz Emacs does not build on RetroBSD, as RetroBSD is missing some functions
|
||||
that Ersatz Emacs requires. It made sense to try to take from each and create
|
||||
an editor that would work.
|
||||
|
||||
In a way, emg has a double meaning: not only is it a combination of
|
||||
the two programs that comprise it, it is also a substitute Mg after my initial
|
||||
port failed.
|
||||
|
||||
I have cleaned up some code where necessary; emg builds without errors on
|
||||
RetroBSD.
|
||||
|
||||
Patches are also very welcome. I ask that you keep in mind the resource
|
||||
constraints of RetroBSD: everything must fit in 96K RAM. But of course,
|
||||
smaller is better.
|
||||
|
||||
I've left Chris Baird's Ersatz Emacs README here so others can better
|
||||
appreciate the history of this software.
|
||||
|
||||
As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
|
||||
|
||||
Versions of emg up to and including 1.2 also supported OpenBSD; OpenBSD
|
||||
has since dropped the older headers, such as sgtty.h, and it is not worth
|
||||
reimplementing these for OpenBSD since OpenBSD maintains Mg.
|
||||
|
||||
====================================
|
||||
Brian Callahan <bcallah@openbsd.org>
|
||||
21
src/cmd/emg/README.md
Normal file
21
src/cmd/emg/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
emg
|
||||
===
|
||||
|
||||
emg, or Ersatz Mg, is a very tiny Emacs-like text editor created by
|
||||
combining elements of Ersatz Emacs and Mg.
|
||||
|
||||
emg is distributed as part of the RetroBSD base system. This repo
|
||||
is for development of emg. New releases are cut from this repo and
|
||||
integrated into RetroBSD.
|
||||
|
||||
You can get a tarball of the latest release at
|
||||
http://devio.us/~bcallah/emg/
|
||||
|
||||
emg is known to work on NetBSD as-is and AIX 5.1L with some small
|
||||
tweaks, for those looking to get involved with emg development.
|
||||
|
||||
emg is Public Domain, because Ersatz Emacs and Mg are both Public
|
||||
Domain and it would be insulting to all involved to change that.
|
||||
|
||||
=================================
|
||||
Brian Callahan <bcallah@devio.us>
|
||||
@@ -12,16 +12,16 @@
|
||||
#include "estruct.h"
|
||||
#include "edef.h"
|
||||
|
||||
extern int getccol(int bflg);
|
||||
extern int getccol(int);
|
||||
extern void mlwrite();
|
||||
extern int mlreplyt();
|
||||
|
||||
int forwchar(int f, int n);
|
||||
int backchar(int f, int n);
|
||||
int forwline(int f, int n);
|
||||
int backline(int f, int n);
|
||||
int pagedown(int f, int n);
|
||||
int pageup(int f, int n);
|
||||
int forwchar(int, int);
|
||||
int backchar(int, int);
|
||||
int forwline(int, int);
|
||||
int backline(int, int);
|
||||
int pagedown(int, int);
|
||||
int pageup(int, int);
|
||||
|
||||
/*
|
||||
* This routine, given a pointer to a LINE, and the current cursor goal
|
||||
@@ -254,24 +254,24 @@ int backline(int f, int n)
|
||||
}
|
||||
|
||||
/*
|
||||
* PgDn. Scroll down (ROWS - 1).
|
||||
* Just forwline(f, (ROWS -1))
|
||||
* PgDn. Scroll down (rows / 2).
|
||||
* Just forwline(f, (rows / 2))
|
||||
* Bound to C-V
|
||||
*/
|
||||
int pagedown(int f, int n)
|
||||
{
|
||||
forwline(f, (ROWS - 1));
|
||||
forwline(f, (rows / 2));
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* PgUp. Scroll up (ROWS - 1).
|
||||
* Just backline(f, (ROWS -1))
|
||||
* PgUp. Scroll up (rows / 2).
|
||||
* Just backline(f, (rows / 2))
|
||||
* Bound to M-V
|
||||
*/
|
||||
int pageup(int f, int n)
|
||||
{
|
||||
backline(f, (ROWS - 1));
|
||||
backline(f, (rows / 2));
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,93 +11,17 @@
|
||||
#include "estruct.h"
|
||||
#include "edef.h"
|
||||
|
||||
extern int mlreply(char *prompt, char *buf, int nbuf);
|
||||
extern int readin(char fname[]);
|
||||
extern int mlreply(char *, char *, int);
|
||||
extern int readin(char []);
|
||||
extern void mlwrite();
|
||||
extern void mlerase();
|
||||
extern int mlyesno(char *prompt);
|
||||
extern void lfree(LINE *lp);
|
||||
extern int mlyesno(char *);
|
||||
extern void lfree(LINE *);
|
||||
extern LINE *lalloc();
|
||||
|
||||
int swbuffer(BUFFER *bp);
|
||||
int addline(char *text);
|
||||
int anycb();
|
||||
BUFFER* bfind(char *bname, int cflag, int bflag);
|
||||
int bclear(BUFFER *bp);
|
||||
|
||||
/*
|
||||
* make buffer BP current
|
||||
*/
|
||||
int swbuffer(BUFFER *bp)
|
||||
{
|
||||
WINDOW *wp;
|
||||
|
||||
if (--curbp->b_nwnd == 0)
|
||||
{ /* Last use. */
|
||||
curbp->b_dotp = curwp->w_dotp;
|
||||
curbp->b_doto = curwp->w_doto;
|
||||
curbp->b_markp = curwp->w_markp;
|
||||
curbp->b_marko = curwp->w_marko;
|
||||
}
|
||||
curbp = bp; /* Switch. */
|
||||
if (curbp->b_active != TRUE)
|
||||
{ /* buffer not active yet */
|
||||
/* read it in and activate it */
|
||||
readin(curbp->b_fname);
|
||||
curbp->b_dotp = lforw(curbp->b_linep);
|
||||
curbp->b_doto = 0;
|
||||
curbp->b_active = TRUE;
|
||||
}
|
||||
curwp->w_bufp = bp;
|
||||
curwp->w_linep = bp->b_linep; /* For macros, ignored */
|
||||
curwp->w_flag |= WFMODE | WFFORCE | WFHARD; /* Quite nasty */
|
||||
if (bp->b_nwnd++ == 0)
|
||||
{ /* First use */
|
||||
curwp->w_dotp = bp->b_dotp;
|
||||
curwp->w_doto = bp->b_doto;
|
||||
curwp->w_markp = bp->b_markp;
|
||||
curwp->w_marko = bp->b_marko;
|
||||
return (TRUE);
|
||||
}
|
||||
wp = wheadp; /* Look for old */
|
||||
while (wp != 0)
|
||||
{
|
||||
if (wp != curwp && wp->w_bufp == bp)
|
||||
{
|
||||
curwp->w_dotp = wp->w_dotp;
|
||||
curwp->w_doto = wp->w_doto;
|
||||
curwp->w_markp = wp->w_markp;
|
||||
curwp->w_marko = wp->w_marko;
|
||||
break;
|
||||
}
|
||||
wp = wp->w_wndp;
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* The argument "text" points to a string. Append this line to the buffer list
|
||||
* buffer. Handcraft the EOL on the end. Return TRUE if it worked and FALSE if
|
||||
* you ran out of room.
|
||||
*/
|
||||
int addline(char *text)
|
||||
{
|
||||
LINE *lp;
|
||||
int ntext, i;
|
||||
|
||||
ntext = strlen(text);
|
||||
if ((lp = lalloc(ntext)) == NULL)
|
||||
return (FALSE);
|
||||
for (i = 0; i < ntext; ++i)
|
||||
lputc(lp, i, text[i]);
|
||||
blistp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */
|
||||
lp->l_bp = blistp->b_linep->l_bp;
|
||||
blistp->b_linep->l_bp = lp;
|
||||
lp->l_fp = blistp->b_linep;
|
||||
if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */
|
||||
blistp->b_dotp = lp; /* move it to new line */
|
||||
return (TRUE);
|
||||
}
|
||||
int anycb(void);
|
||||
BUFFER *bfind(char *);
|
||||
int bclear(BUFFER *);
|
||||
|
||||
/*
|
||||
* Look through the list of buffers. Return TRUE if there are any changed
|
||||
@@ -105,13 +29,12 @@ int addline(char *text)
|
||||
* cares if the list of buffer names is hacked. Return FALSE if no buffers
|
||||
* have been changed.
|
||||
*/
|
||||
int anycb()
|
||||
int anycb(void)
|
||||
{
|
||||
BUFFER *bp;
|
||||
|
||||
bp = bheadp;
|
||||
while (bp != NULL)
|
||||
{
|
||||
while (bp != NULL) {
|
||||
if ((bp->b_flag & BFTEMP) == 0 && (bp->b_flag & BFCHG) != 0)
|
||||
return (TRUE);
|
||||
bp = bp->b_bufp;
|
||||
@@ -122,50 +45,40 @@ int anycb()
|
||||
/*
|
||||
* Find a buffer, by name. Return a pointer to the BUFFER structure associated
|
||||
* with it. If the named buffer is found, but is a TEMP buffer (like the
|
||||
* buffer list) conplain. If the buffer is not found and the "cflag" is TRUE,
|
||||
* create it. The "bflag" is the settings for the flags in in buffer.
|
||||
* buffer list), complain.
|
||||
*/
|
||||
BUFFER* bfind(char *bname, int cflag, int bflag)
|
||||
BUFFER *
|
||||
bfind(char *fname)
|
||||
{
|
||||
BUFFER *bp, *sb;
|
||||
LINE *lp;
|
||||
|
||||
bp = bheadp;
|
||||
while (bp != 0)
|
||||
{
|
||||
if (strcmp(bname, bp->b_bname) == 0)
|
||||
{
|
||||
if ((bp->b_flag & BFTEMP) != 0)
|
||||
{
|
||||
while (bp != 0) {
|
||||
if (strcmp(fname, bp->b_fname) == 0) {
|
||||
if ((bp->b_flag & BFTEMP) != 0) {
|
||||
mlwrite("Cannot select builtin buffer");
|
||||
return (0);
|
||||
return (FALSE);
|
||||
}
|
||||
return (bp);
|
||||
}
|
||||
bp = bp->b_bufp;
|
||||
}
|
||||
if (cflag != FALSE)
|
||||
{
|
||||
if ((bp = (BUFFER *) malloc(sizeof(BUFFER))) == NULL)
|
||||
return (0);
|
||||
if ((lp = lalloc(0)) == NULL)
|
||||
{
|
||||
return (FALSE);
|
||||
if ((lp = lalloc(0)) == NULL) {
|
||||
free(bp);
|
||||
return (BUFFER *)0;
|
||||
}
|
||||
/* find the place in the list to insert this buffer */
|
||||
if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0)
|
||||
{
|
||||
if (bheadp == NULL || strcmp(bheadp->b_fname, fname) > 0) {
|
||||
/* insert at the begining */
|
||||
bp->b_bufp = bheadp;
|
||||
bheadp = bp;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
sb = bheadp;
|
||||
while (sb->b_bufp != 0)
|
||||
{
|
||||
if (strcmp(sb->b_bufp->b_bname, bname) > 0)
|
||||
while (sb->b_bufp != 0) {
|
||||
if (strcmp(sb->b_bufp->b_fname, fname) > 0)
|
||||
break;
|
||||
sb = sb->b_bufp;
|
||||
}
|
||||
@@ -176,20 +89,15 @@ BUFFER* bfind(char *bname, int cflag, int bflag)
|
||||
}
|
||||
|
||||
/* and set up the other buffer fields */
|
||||
bp->b_active = TRUE;
|
||||
bp->b_dotp = lp;
|
||||
bp->b_doto = 0;
|
||||
bp->b_markp = 0;
|
||||
bp->b_marko = 0;
|
||||
bp->b_flag = (char)bflag;
|
||||
bp->b_nwnd = 0;
|
||||
bp->b_flag = 0;
|
||||
bp->b_linep = lp;
|
||||
bp->b_lines = 1;
|
||||
strncpy(bp->b_fname, "", 1);
|
||||
strncpy(bp->b_bname, bname, NBUFN);
|
||||
lp->l_fp = lp;
|
||||
lp->l_bp = lp;
|
||||
}
|
||||
return (bp);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,28 +17,28 @@ extern int typeahead();
|
||||
extern int ctrlg();
|
||||
extern int getccol();
|
||||
|
||||
void movecursor(int row, int col);
|
||||
void movecursor(int, int);
|
||||
void mlerase();
|
||||
int refresh();
|
||||
void vtinit();
|
||||
void vttidy();
|
||||
void vtmove(int row, int col);
|
||||
void vtputc(int c);
|
||||
void vtpute(int c);
|
||||
int vtputs(const char *s);
|
||||
void vtmove(int, int);
|
||||
void vtputc(int);
|
||||
void vtpute(int);
|
||||
int vtputs(const char *);
|
||||
void vteeol();
|
||||
void update();
|
||||
void updext();
|
||||
void updateline(int row, char vline[], char pline[], short *flags);
|
||||
void modeline(WINDOW *wp);
|
||||
void updateline(int, char [], char [], short *);
|
||||
void modeline(WINDOW *);
|
||||
void upmode();
|
||||
int mlyesno(char *prompt);
|
||||
int mlreplyt(char *prompt, char *buf, int nbuf, char eolchar);
|
||||
int mlreply(char *prompt, char *buf, int nbuf);
|
||||
int mlyesno(char *);
|
||||
int mlreplyt(char *, char *, int, char);
|
||||
int mlreply(char *, char *, int);
|
||||
void mlwrite();
|
||||
void mlputs(char *s);
|
||||
void mlputi(int i, int r);
|
||||
void mlputli(long l, int r);
|
||||
void mlputs(char *);
|
||||
void mlputi(int, int);
|
||||
void mlputli(long, int);
|
||||
|
||||
typedef struct VIDEO {
|
||||
short v_flag; /* Flags */
|
||||
@@ -1001,4 +1001,3 @@ void mlputli(long l, int r)
|
||||
(*term.t_putchar) ((int) (l % r) + '0');
|
||||
++ttcol;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,9 +50,12 @@ KEYTAB keytab[] = {
|
||||
{META | 'S', forwsearch}, /* non-standard */
|
||||
{META | 'V', pageup},
|
||||
{META | 'W', copyregion},
|
||||
{META | 'Z', quickexit},
|
||||
{METE | 'A', backline},
|
||||
{METE | 'B', forwline},
|
||||
{METE | 'C', forwchar},
|
||||
{METE | 'D', backchar},
|
||||
{METE | '5', pageup},
|
||||
{METE | '6', pagedown},
|
||||
{0x7F, backdel},
|
||||
{META | '[', extendedcmd},
|
||||
{META | 'O', extendedcmd},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
@@ -26,11 +26,11 @@ int curcol; /* Cursor column */
|
||||
int thisflag; /* Flags, this command */
|
||||
int lastflag; /* Flags, last command */
|
||||
int curgoal; /* Goal for C-P, C-N */
|
||||
int rows; /* Screen rows for C-V, M-V */
|
||||
WINDOW *curwp; /* Current window */
|
||||
BUFFER *curbp; /* Current buffer */
|
||||
WINDOW *wheadp; /* Head of list of windows */
|
||||
BUFFER *bheadp; /* Head of list of buffers */
|
||||
BUFFER *blistp; /* Buffer for C-X C-B */
|
||||
short *kbdmip; /* Input pointer for above */
|
||||
short *kbdmop; /* Output pointer for above */
|
||||
|
||||
@@ -61,18 +61,14 @@ extern int curcol; /* Cursor column */
|
||||
extern int thisflag; /* Flags, this command */
|
||||
extern int lastflag; /* Flags, last command */
|
||||
extern int curgoal; /* Goal for C-P, C-N */
|
||||
extern int rows; /* Screen rows for C-V, M-V */
|
||||
extern WINDOW *curwp; /* Current window */
|
||||
extern BUFFER *curbp; /* Current buffer */
|
||||
extern WINDOW *wheadp; /* Head of list of windows */
|
||||
extern BUFFER *bheadp; /* Head of list of buffers */
|
||||
extern BUFFER *blistp; /* Buffer for C-X C-B */
|
||||
extern short *kbdmip; /* Input pointer for above */
|
||||
extern short *kbdmop; /* Output pointer for above */
|
||||
|
||||
#endif
|
||||
|
||||
/* terminal table defined only in TERM.C */
|
||||
|
||||
#ifndef termdef
|
||||
extern TERM term; /* Terminal information */
|
||||
#endif
|
||||
|
||||
@@ -44,11 +44,9 @@ extern int killtext(); /* Kill forward */
|
||||
extern int yank(); /* Yank back from killbuffer */
|
||||
extern int killregion(); /* Kill region */
|
||||
extern int copyregion(); /* Copy region to kill buffer */
|
||||
extern int quickexit(); /* low keystroke style exit */
|
||||
extern int setline(); /* go to a numbered line */
|
||||
extern int deskey(); /* describe a key's binding */
|
||||
extern int insfile(); /* insert a file */
|
||||
extern int forwhunt(); /* hunt forward for next match */
|
||||
extern int backhunt(); /* hunt backwards for next match */
|
||||
extern int extendedcmd(); /* parse ANSI/VT100 extended keys */
|
||||
extern int showversion(); /* show emacs version */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
.\" Basic emg man page.
|
||||
.\" As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
|
||||
.\"
|
||||
.Dd August 9, 2014
|
||||
.Dd August 9, 2015
|
||||
.Os
|
||||
.Dt EMG 1
|
||||
.Sh NAME
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
emg keybindings (August 9, 2014)
|
||||
emg keybindings (August 9, 2015)
|
||||
Based on Ersatz Emacs (2000/09/14)
|
||||
|
||||
M- means to use the <ESC> key prior to using another key
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define CTRL 0x0100 /* Control flag, or'ed in */
|
||||
#define META 0x0200 /* Meta flag, or'ed in */
|
||||
#define CTLX 0x0400 /* ^X flag, or'ed in */
|
||||
#define METE 0x0800 /* M-[ flag, or'ed in */
|
||||
|
||||
#define FALSE 0 /* False, no, bad, etc */
|
||||
#define TRUE 1 /* True, yes, good, etc */
|
||||
@@ -31,35 +32,6 @@
|
||||
#define CFCPCN 0x0001 /* Last command was C-P, C-N */
|
||||
#define CFKILL 0x0002 /* Last command was a kill */
|
||||
|
||||
/*
|
||||
* screen constants
|
||||
* override with
|
||||
* CFLAGS += -DCOLS=XXX -DROWS=XXX
|
||||
*/
|
||||
#ifndef COLS
|
||||
#define COLS 80
|
||||
#endif
|
||||
|
||||
#ifndef ROWS
|
||||
#define ROWS 24
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX:
|
||||
* Default/sane(?) maximum column and row sizes.
|
||||
* Taken from mg1a.
|
||||
*
|
||||
* Let the user override these with
|
||||
* CFLAGS += -DMAXCOL=XXX -DMAXROW=XXX
|
||||
*/
|
||||
#ifndef MAXCOL
|
||||
#define MAXCOL 132
|
||||
#endif
|
||||
|
||||
#ifndef MAXROW
|
||||
#define MAXROW 66
|
||||
#endif
|
||||
|
||||
/*
|
||||
* There is a window structure allocated for every active display window. The
|
||||
* windows are kept in a big list, in top to bottom screen order, with the
|
||||
@@ -95,12 +67,9 @@ typedef struct WINDOW
|
||||
* Text is kept in buffers. A buffer header, described below, exists for every
|
||||
* buffer in the system. The buffers are kept in a big list, so that commands
|
||||
* that search for a buffer by name can find the buffer header. There is a
|
||||
* safe store for the dot and mark in the header, but this is only valid if
|
||||
* the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
|
||||
* the buffer is kept in a circularly linked list of lines, with a pointer to
|
||||
* the header line in "b_linep". Buffers may be "Inactive" which means the
|
||||
* files accosiated with them have not been read in yet. These get read in at
|
||||
* "use buffer" time
|
||||
* safe store for the dot and mark in the header. The text for the buffer is
|
||||
* kept in a circularly linked list of lines, with a pointer to the header
|
||||
* line in "b_linep".
|
||||
*/
|
||||
typedef struct BUFFER
|
||||
{
|
||||
@@ -110,11 +79,8 @@ typedef struct BUFFER
|
||||
struct LINE *b_markp; /* The same as the above two, */
|
||||
long b_marko; /* but for the "mark" */
|
||||
struct LINE *b_linep; /* Link to the header LINE */
|
||||
char b_active; /* window activated flag */
|
||||
char b_nwnd; /* Count of windows on buffer */
|
||||
char b_flag; /* Flags */
|
||||
char b_fname[NFILEN]; /* File name */
|
||||
char b_bname[NBUFN]; /* Buffer name */
|
||||
int b_lines; /* Number of lines in file */
|
||||
} BUFFER;
|
||||
|
||||
|
||||
@@ -9,40 +9,37 @@
|
||||
#include "estruct.h"
|
||||
#include "edef.h"
|
||||
|
||||
extern int mlreply(char *prompt, char *buf, int nbuf);
|
||||
extern int swbuffer(BUFFER *bp);
|
||||
extern int mlreply(char *, char *, int);
|
||||
extern void mlwrite();
|
||||
extern int bclear(BUFFER *bp);
|
||||
extern int ffropen(char *fn);
|
||||
extern int ffgetline(char buf[], int nbuf);
|
||||
extern int ffwopen(char *fn);
|
||||
extern int bclear(BUFFER *);
|
||||
extern int ffropen(char *);
|
||||
extern int ffgetline(char [], int);
|
||||
extern int ffwopen(char *);
|
||||
extern int ffclose();
|
||||
extern int ffputline(char buf[], int nbuf);
|
||||
extern int ffputline(char [], int);
|
||||
extern BUFFER *bfind();
|
||||
extern LINE *lalloc();
|
||||
|
||||
int fileread(int f, int n);
|
||||
int insfile(int f, int n);
|
||||
int getfile(char fname[]);
|
||||
int readin(char fname[]);
|
||||
void makename(char bname[], char fname[]);
|
||||
int filewrite(int f, int n);
|
||||
int filesave(int f, int n);
|
||||
int writeout(char *fn);
|
||||
int filename(int f, int n);
|
||||
int ifile(char fname[]);
|
||||
int fileread(int, int);
|
||||
int insfile(int, int);
|
||||
int readin(char []);
|
||||
int filewrite(int, int);
|
||||
int filesave(int, int);
|
||||
int writeout(char *);
|
||||
int filename(int, int);
|
||||
int ifile(char []);
|
||||
|
||||
/*
|
||||
* Read a file into the current buffer. This is really easy; all you do it
|
||||
* find the name of the file, and call the standard "read a file into the
|
||||
* current buffer" code. Bound to "C-X C-R"
|
||||
* current buffer" code. Bound to "C-X C-F"
|
||||
*/
|
||||
int fileread(int f, int n)
|
||||
{
|
||||
int s;
|
||||
char fname[NFILEN];
|
||||
|
||||
if ((s = mlreply("Read file: ", fname, NFILEN)) != TRUE)
|
||||
if ((s = mlreply("Open file: ", fname, NFILEN)) != TRUE)
|
||||
return (s);
|
||||
return (readin(fname));
|
||||
}
|
||||
@@ -62,65 +59,6 @@ int insfile(int f, int n)
|
||||
return (ifile(fname));
|
||||
}
|
||||
|
||||
int getfile(char fname[])
|
||||
{
|
||||
BUFFER *bp;
|
||||
LINE *lp;
|
||||
char bname[NBUFN]; /* buffer name to put file */
|
||||
int i, s;
|
||||
|
||||
for (bp = bheadp; bp != (BUFFER*)0; bp = bp->b_bufp)
|
||||
{
|
||||
if ((bp->b_flag & BFTEMP) == 0 && strcmp(bp->b_fname, fname) == 0)
|
||||
{
|
||||
if (--curbp->b_nwnd == 0)
|
||||
{
|
||||
curbp->b_dotp = curwp->w_dotp;
|
||||
curbp->b_doto = curwp->w_doto;
|
||||
curbp->b_markp = curwp->w_markp;
|
||||
curbp->b_marko = curwp->w_marko;
|
||||
}
|
||||
swbuffer(bp);
|
||||
lp = curwp->w_dotp;
|
||||
i = curwp->w_ntrows / 2;
|
||||
while (i-- && lback(lp) != curbp->b_linep)
|
||||
lp = lback(lp);
|
||||
curwp->w_linep = lp;
|
||||
curwp->w_flag |= WFMODE | WFHARD;
|
||||
mlwrite("[Old buffer]");
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
makename(bname, fname); /* New buffer name */
|
||||
while ((bp = bfind(bname, FALSE, 0)) != (BUFFER*)0)
|
||||
{
|
||||
s = mlreply("Buffer name: ", bname, NBUFN);
|
||||
if (s == ABORT) /* ^G to just quit */
|
||||
return (s);
|
||||
if (s == FALSE)
|
||||
{ /* CR to clobber it */
|
||||
makename(bname, fname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bp == (BUFFER*)0 && (bp = bfind(bname, TRUE, 0)) == (BUFFER*)0)
|
||||
{
|
||||
mlwrite("Cannot create buffer");
|
||||
return (FALSE);
|
||||
}
|
||||
if (--curbp->b_nwnd == 0)
|
||||
{ /* Undisplay */
|
||||
curbp->b_dotp = curwp->w_dotp;
|
||||
curbp->b_doto = curwp->w_doto;
|
||||
curbp->b_markp = curwp->w_markp;
|
||||
curbp->b_marko = curwp->w_marko;
|
||||
}
|
||||
curbp = bp; /* Switch to it */
|
||||
curwp->w_bufp = bp;
|
||||
curbp->b_nwnd++;
|
||||
return (readin(fname)); /* Read it in */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read file "fname" into the current buffer, blowing away any text found
|
||||
* there. Called by both the read and find commands. Return the final status
|
||||
@@ -196,6 +134,7 @@ int readin(char fname[])
|
||||
wp->w_doto = 0;
|
||||
wp->w_markp = NULL;
|
||||
wp->w_marko = 0;
|
||||
wp->w_dotline = 0;
|
||||
wp->w_flag |= WFMODE | WFHARD;
|
||||
}
|
||||
}
|
||||
@@ -204,27 +143,6 @@ int readin(char fname[])
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take a file name, and from it fabricate a buffer name. This routine knows
|
||||
* about the syntax of file names on the target system. I suppose that this
|
||||
* information could be put in a better place than a line of code.
|
||||
*/
|
||||
void makename(char bname[], char fname[])
|
||||
{
|
||||
char *cp1, *cp2;
|
||||
|
||||
cp1 = &fname[0];
|
||||
while (*cp1 != 0)
|
||||
++cp1;
|
||||
|
||||
while (cp1 != &fname[0] && cp1[-1] != '/')
|
||||
--cp1;
|
||||
cp2 = &bname[0];
|
||||
while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != ';')
|
||||
*cp2++ = *cp1++;
|
||||
*cp2 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask for a file name, and write the contents of the current buffer to that
|
||||
* file. Update the remembered file name and clear the buffer changed flag.
|
||||
@@ -267,7 +185,7 @@ int filesave(int f, int n)
|
||||
|
||||
if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes */
|
||||
return (TRUE);
|
||||
if (curbp->b_fname[0] == 0)
|
||||
if (curbp->b_fname[0] == '\0')
|
||||
filename(f, n); /* Must have a name */
|
||||
if ((s = writeout(curbp->b_fname)) == TRUE)
|
||||
{
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
extern void mlwrite();
|
||||
|
||||
int ffropen(char *fn);
|
||||
int ffwopen(char *fn);
|
||||
int ffropen(char *);
|
||||
int ffwopen(char *);
|
||||
int ffclose();
|
||||
int ffputline(char buf[], int nbuf);
|
||||
int ffgetline(char buf[], int nbuf);
|
||||
int ffputline(char [], int);
|
||||
int ffgetline(char [], int);
|
||||
|
||||
FILE *ffp; /* File pointer, all functions */
|
||||
|
||||
|
||||
@@ -6,12 +6,6 @@
|
||||
* and window structures, to make sure that the necessary updating gets done.
|
||||
* There are routines in this file that handle the kill buffer too. It isn't
|
||||
* here for any good reason.
|
||||
*
|
||||
* Note that this code only updates the dot and mark values in the window
|
||||
* list. Since all the code acts on the current window, the buffer that we are
|
||||
* editing must be being displayed, which means that "b_nwnd" is non zero,
|
||||
* which means that the dot and mark values in the buffer headers are
|
||||
* nonsense
|
||||
*/
|
||||
|
||||
#include <stdlib.h> /* malloc(3) */
|
||||
@@ -19,18 +13,18 @@
|
||||
#include "edef.h"
|
||||
|
||||
extern void mlwrite();
|
||||
extern int backchar(int f, int n);
|
||||
extern int backchar(int, int);
|
||||
|
||||
LINE* lalloc(int used);
|
||||
void lfree(LINE *lp);
|
||||
void lchange(int flag);
|
||||
int linsert(int n, int c);
|
||||
LINE* lalloc(int);
|
||||
void lfree(LINE *);
|
||||
void lchange(int);
|
||||
int linsert(int, int);
|
||||
int lnewline();
|
||||
int ldelete(int n, int kflag);
|
||||
int ldelete(int, int);
|
||||
int ldelnewline();
|
||||
void kdelete();
|
||||
int kinsert(int c);
|
||||
int kremove(int n);
|
||||
int kinsert(int);
|
||||
int kremove(int);
|
||||
|
||||
#define NBLOCK 16 /* Line block chunk size */
|
||||
#define KBLOCK 1024 /* Kill buffer block size */
|
||||
@@ -45,7 +39,8 @@ unsigned long ksize = 0; /* # of bytes allocated in KB */
|
||||
* a pointer to the new block, or NULL if there isn't any memory left. Print a
|
||||
* message in the message line if no space.
|
||||
*/
|
||||
LINE* lalloc(int used)
|
||||
LINE *
|
||||
lalloc(int used)
|
||||
{
|
||||
LINE *lp;
|
||||
int size;
|
||||
@@ -69,7 +64,8 @@ LINE* lalloc(int used)
|
||||
* might be in. Release the memory. The buffers are updated too; the magic
|
||||
* conditions described in the above comments don't hold here
|
||||
*/
|
||||
void lfree(LINE *lp)
|
||||
void
|
||||
lfree(LINE *lp)
|
||||
{
|
||||
BUFFER *bp;
|
||||
WINDOW *wp;
|
||||
@@ -92,21 +88,15 @@ void lfree(LINE *lp)
|
||||
wp = wp->w_wndp;
|
||||
}
|
||||
bp = bheadp;
|
||||
while (bp != NULL)
|
||||
{
|
||||
if (bp->b_nwnd == 0)
|
||||
{
|
||||
if (bp->b_dotp == lp)
|
||||
{
|
||||
while (bp != NULL) {
|
||||
if (bp->b_dotp == lp) {
|
||||
bp->b_dotp = lp->l_fp;
|
||||
bp->b_doto = 0;
|
||||
}
|
||||
if (bp->b_markp == lp)
|
||||
{
|
||||
if (bp->b_markp == lp) {
|
||||
bp->b_markp = lp->l_fp;
|
||||
bp->b_marko = 0;
|
||||
}
|
||||
}
|
||||
bp = bp->b_bufp;
|
||||
}
|
||||
lp->l_bp->l_fp = lp->l_fp;
|
||||
@@ -117,24 +107,20 @@ void lfree(LINE *lp)
|
||||
/*
|
||||
* This routine gets called when a character is changed in place in the
|
||||
* current buffer. It updates all of the required flags in the buffer and
|
||||
* window system. The flag used is passed as an argument; if the buffer is
|
||||
* being displayed in more than 1 window we change EDIT t HARD. Set MODE if
|
||||
* the mode line needs to be updated (the "*" has to be set).
|
||||
* window system. The flag used is passed as an argument. Set MODE if the
|
||||
* mode line needs to be updated (the "**" has to be set).
|
||||
*/
|
||||
void lchange(int flag)
|
||||
void
|
||||
lchange(int flag)
|
||||
{
|
||||
WINDOW *wp;
|
||||
|
||||
if (curbp->b_nwnd != 1) /* Ensure hard */
|
||||
flag = WFHARD;
|
||||
if ((curbp->b_flag & BFCHG) == 0)
|
||||
{ /* First change, so */
|
||||
if ((curbp->b_flag & BFCHG) == 0) { /* First change, so */
|
||||
flag |= WFMODE; /* update mode lines */
|
||||
curbp->b_flag |= BFCHG;
|
||||
}
|
||||
wp = wheadp;
|
||||
while (wp != NULL)
|
||||
{
|
||||
while (wp != NULL) {
|
||||
if (wp->w_bufp == curbp)
|
||||
wp->w_flag |= flag;
|
||||
wp = wp->w_wndp;
|
||||
@@ -150,7 +136,8 @@ void lchange(int flag)
|
||||
* greater than the place where you did the insert. Return TRUE if all is
|
||||
* well, and FALSE on errors
|
||||
*/
|
||||
int linsert(int n, int c)
|
||||
int
|
||||
linsert(int n, int c)
|
||||
{
|
||||
WINDOW *wp;
|
||||
LINE *lp1, *lp2, *lp3;
|
||||
@@ -238,7 +225,8 @@ int linsert(int n, int c)
|
||||
* update of dot and mark is a bit easier then in the above case, because the
|
||||
* split forces more updating.
|
||||
*/
|
||||
int lnewline()
|
||||
int
|
||||
lnewline()
|
||||
{
|
||||
WINDOW *wp;
|
||||
char *cp1, *cp2;
|
||||
@@ -296,7 +284,8 @@ int lnewline()
|
||||
* deleted, and FALSE if they were not (because dot ran into the end of the
|
||||
* buffer. The "kflag" is TRUE if the text should be put in the kill buffer.
|
||||
*/
|
||||
int ldelete(int n, int kflag)
|
||||
int
|
||||
ldelete(int n, int kflag)
|
||||
{
|
||||
LINE *dotp;
|
||||
WINDOW *wp;
|
||||
@@ -368,7 +357,8 @@ int ldelete(int n, int kflag)
|
||||
* require that lines be moved about in memory. Return FALSE on error and TRUE
|
||||
* if all looks ok. Called by "ldelete" only.
|
||||
*/
|
||||
int ldelnewline()
|
||||
int
|
||||
ldelnewline()
|
||||
{
|
||||
LINE *lp1, *lp2, *lp3;
|
||||
WINDOW *wp;
|
||||
@@ -457,10 +447,10 @@ int ldelnewline()
|
||||
* new kill context is being created. The kill buffer array is released, just
|
||||
* in case the buffer has grown to immense size. No errors.
|
||||
*/
|
||||
void kdelete()
|
||||
{
|
||||
if (kbufp != NULL)
|
||||
void
|
||||
kdelete()
|
||||
{
|
||||
if (kbufp != NULL) {
|
||||
free((char *) kbufp);
|
||||
kbufp = NULL;
|
||||
kused = 0;
|
||||
@@ -474,7 +464,8 @@ void kdelete()
|
||||
* put something in the kill buffer you are going to put more stuff there too
|
||||
* later. Return TRUE if all is well, and FALSE on errors.
|
||||
*/
|
||||
int kinsert(int c)
|
||||
int
|
||||
kinsert(int c)
|
||||
{
|
||||
char *nbufp;
|
||||
|
||||
@@ -498,7 +489,8 @@ int kinsert(int c)
|
||||
* "n" is off the end, it returns "-1". This lets the caller just scan along
|
||||
* until it gets a "-1" back.
|
||||
*/
|
||||
int kremove(int n)
|
||||
int
|
||||
kremove(int n)
|
||||
{
|
||||
if (n >= kused)
|
||||
return (-1);
|
||||
|
||||
@@ -22,73 +22,53 @@ extern void vttidy();
|
||||
extern void update();
|
||||
extern void mlerase();
|
||||
extern void mlwrite();
|
||||
extern int mlyesno(char *prompt);
|
||||
extern void makename(char bname[], char fname[]);
|
||||
extern int readin(char fname[]);
|
||||
extern int linsert(int f, int n);
|
||||
extern int anycb();
|
||||
extern BUFFER *bfind();
|
||||
extern int mlyesno(char *);
|
||||
extern int readin(char []);
|
||||
extern int linsert(int, int);
|
||||
extern int anycb(void);
|
||||
extern BUFFER *bfind(char *);
|
||||
|
||||
void edinit(char bname[]);
|
||||
int execute(int c, int f, int n);
|
||||
int getkey();
|
||||
int getctl();
|
||||
int quickexit(int f, int n);
|
||||
int quit(int f, int n);
|
||||
int ctlxlp(int f, int n);
|
||||
int ctlxrp(int f, int n);
|
||||
int ctlxe(int f, int n);
|
||||
int ctrlg(int f, int n);
|
||||
int extendedcmd(int f, int n);
|
||||
void edinit(char []);
|
||||
int execute(int, int, int);
|
||||
int getkey(void);
|
||||
int getctl(void);
|
||||
int quit(int, int);
|
||||
int ctlxlp(int, int);
|
||||
int ctlxrp(int, int);
|
||||
int ctlxe(int, int);
|
||||
int ctrlg(int, int);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
BUFFER *bp;
|
||||
char bname[NBUFN]; /* buffer name of file to read */
|
||||
char fname[NFILEN];
|
||||
int c, f, n, mflag;
|
||||
int ffile; /* first file flag */
|
||||
int basec; /* c stripped of meta character */
|
||||
|
||||
/* initialize the editor and process the startup file */
|
||||
getwinsize(); /* find out the "real" screen size */
|
||||
strncpy(bname, "main", 5); /* default buffer name */
|
||||
edinit(bname); /* Buffers, windows */
|
||||
vtinit(); /* Displays */
|
||||
ffile = TRUE; /* no file to edit yet */
|
||||
update(); /* let the user know we are here */
|
||||
|
||||
/* scan through the command line and get the files to edit */
|
||||
/* In place of getopt() */
|
||||
if (argc > 2) {
|
||||
(void) fprintf(stderr, "Can only edit one file at a time\n");
|
||||
(void) fprintf(stderr, "usage: emg [file]\n");
|
||||
exit(1);
|
||||
} else if (argc == 2) {
|
||||
/* set up a buffer for this file */
|
||||
makename(bname, argv[1]);
|
||||
|
||||
/* if this is the first file, read it in */
|
||||
if (ffile)
|
||||
{
|
||||
bp = curbp;
|
||||
makename(bname, argv[1]);
|
||||
strncpy(bp->b_bname, bname, NBUFN);
|
||||
strncpy(bp->b_fname, argv[1], NFILEN);
|
||||
if (readin(argv[1]) == ABORT)
|
||||
{
|
||||
strncpy(bp->b_bname, "main", 5);
|
||||
strncpy(bp->b_fname, "", 1);
|
||||
strncpy(fname, argv[1], NFILEN);
|
||||
} else {
|
||||
strncpy(fname, "*scratch*", NFILEN);
|
||||
}
|
||||
|
||||
/* initialize the editor and process the startup file */
|
||||
getwinsize(); /* Find out the "real" screen size */
|
||||
edinit(fname); /* Buffers, windows */
|
||||
vtinit(); /* Displays */
|
||||
update(); /* Let the user know we are here */
|
||||
|
||||
/* Read in the file given on the command line */
|
||||
if (argc == 2) {
|
||||
bp = curbp;
|
||||
if (readin(argv[1]) == ABORT)
|
||||
strncpy(fname, "*scratch*", NFILEN);
|
||||
bp->b_dotp = bp->b_linep;
|
||||
bp->b_doto = 0;
|
||||
ffile = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set this to inactive */
|
||||
bp = bfind(bname, TRUE, 0);
|
||||
strncpy(bp->b_fname, argv[1], NFILEN);
|
||||
bp->b_active = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup to process commands */
|
||||
@@ -98,8 +78,7 @@ main(int argc, char *argv[])
|
||||
loop:
|
||||
update(); /* Fix up the screen */
|
||||
c = getkey();
|
||||
if (mpresf != FALSE)
|
||||
{
|
||||
if (mpresf != FALSE) {
|
||||
mlerase();
|
||||
update();
|
||||
}
|
||||
@@ -109,22 +88,18 @@ main(int argc, char *argv[])
|
||||
/* do META-# processing if needed */
|
||||
|
||||
basec = c & ~META; /* strip meta char off if there */
|
||||
if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-'))
|
||||
{
|
||||
if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-')) {
|
||||
f = TRUE; /* there is a # arg */
|
||||
n = 0; /* start with a zero default */
|
||||
mflag = 1; /* current minus flag */
|
||||
c = basec; /* strip the META */
|
||||
while ((c >= '0' && c <= '9') || (c == '-'))
|
||||
{
|
||||
if (c == '-')
|
||||
{
|
||||
while ((c >= '0' && c <= '9') || (c == '-')) {
|
||||
if (c == '-') {
|
||||
/* already hit a minus or digit? */
|
||||
if ((mflag == -1) || (n != 0))
|
||||
break;
|
||||
mflag = -1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
n = n * 10 + (c - '0');
|
||||
if ((n == 0) && (mflag == -1)) /* lonely - */
|
||||
mlwrite("Arg:");
|
||||
@@ -135,38 +110,32 @@ main(int argc, char *argv[])
|
||||
}
|
||||
n = n * mflag; /* figure in the sign */
|
||||
}
|
||||
/* do ^U repeat argument processing */
|
||||
|
||||
if (c == (CTRL | 'U'))
|
||||
{ /* ^U, start argument */
|
||||
/* do ^U repeat argument processing */
|
||||
if (c == (CTRL | 'U')) { /* ^U, start argument */
|
||||
f = TRUE;
|
||||
n = 4; /* with argument of 4 */
|
||||
mflag = 0; /* that can be discarded */
|
||||
mlwrite("Arg: 4");
|
||||
while (((c = getkey()) >= '0')
|
||||
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-')))
|
||||
{
|
||||
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-'))) {
|
||||
if (c == (CTRL | 'U'))
|
||||
n = n * 4;
|
||||
/*
|
||||
* If dash, and start of argument string, set arg.
|
||||
* to -1. Otherwise, insert it.
|
||||
*/
|
||||
else if (c == '-')
|
||||
{
|
||||
else if (c == '-') {
|
||||
if (mflag)
|
||||
break;
|
||||
n = 0;
|
||||
mflag = -1;
|
||||
}
|
||||
/*
|
||||
* If first digit entered, replace previous argument
|
||||
* with digit and set sign. Otherwise, append to arg.
|
||||
*/
|
||||
else
|
||||
{
|
||||
if (!mflag)
|
||||
{
|
||||
} else {
|
||||
if (!mflag) {
|
||||
n = 0;
|
||||
mflag = 1;
|
||||
}
|
||||
@@ -178,25 +147,24 @@ main(int argc, char *argv[])
|
||||
* Make arguments preceded by a minus sign negative and change
|
||||
* the special argument "^U -" to an effective "^U -1".
|
||||
*/
|
||||
if (mflag == -1)
|
||||
{
|
||||
if (mflag == -1) {
|
||||
if (n == 0)
|
||||
n++;
|
||||
n = -n;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == (CTRL | 'X')) /* ^X is a prefix */
|
||||
if (c == (META | '[')) /* M-[ is extended ANSI sequence */
|
||||
c = METE | getctl();
|
||||
else if (c == (CTRL | 'X')) /* ^X is a prefix */
|
||||
c = CTLX | getctl();
|
||||
if (kbdmip != NULL)
|
||||
{ /* Save macro strokes */
|
||||
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6])
|
||||
{
|
||||
|
||||
if (kbdmip != NULL) { /* Save macro strokes */
|
||||
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6]) {
|
||||
ctrlg(FALSE, 0);
|
||||
goto loop;
|
||||
}
|
||||
if (f != FALSE)
|
||||
{
|
||||
if (f != FALSE) {
|
||||
*kbdmip++ = (CTRL | 'U');
|
||||
*kbdmip++ = n;
|
||||
}
|
||||
@@ -211,22 +179,21 @@ main(int argc, char *argv[])
|
||||
* as an argument, because the main routine may have been told to read in a
|
||||
* file by default, and we want the buffer name to be right.
|
||||
*/
|
||||
void edinit(char bname[])
|
||||
void
|
||||
edinit(char fname[])
|
||||
{
|
||||
BUFFER *bp;
|
||||
WINDOW *wp;
|
||||
|
||||
bp = bfind(bname, TRUE, 0); /* First buffer */
|
||||
blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */
|
||||
wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
|
||||
if (bp == NULL || wp == NULL || blistp == NULL)
|
||||
bp = bfind(fname);
|
||||
wp = (WINDOW *) malloc(sizeof(WINDOW));
|
||||
if (bp == NULL || wp == NULL)
|
||||
exit(1);
|
||||
curbp = bp; /* Make this current */
|
||||
wheadp = wp;
|
||||
curwp = wp;
|
||||
wp->w_wndp = NULL; /* Initialize window */
|
||||
wp->w_bufp = bp;
|
||||
bp->b_nwnd = 1; /* Displayed */
|
||||
wp->w_linep = bp->b_linep;
|
||||
wp->w_dotp = bp->b_linep;
|
||||
wp->w_doto = 0;
|
||||
@@ -244,16 +211,15 @@ void edinit(char bname[])
|
||||
* and arranges to move it to the "lastflag", so that the next command can
|
||||
* look at it. Return the status of command.
|
||||
*/
|
||||
int execute(int c, int f, int n)
|
||||
int
|
||||
execute(int c, int f, int n)
|
||||
{
|
||||
KEYTAB *ktp;
|
||||
int status;
|
||||
|
||||
ktp = &keytab[0]; /* Look in key table */
|
||||
while (ktp->k_fp != NULL)
|
||||
{
|
||||
if (ktp->k_code == c)
|
||||
{
|
||||
while (ktp->k_fp != NULL) {
|
||||
if (ktp->k_code == c) {
|
||||
thisflag = 0;
|
||||
status = (*ktp->k_fp) (f, n);
|
||||
lastflag = thisflag;
|
||||
@@ -263,10 +229,8 @@ int execute(int c, int f, int n)
|
||||
}
|
||||
|
||||
if ((c >= 0x20 && c <= 0x7E) /* Self inserting */
|
||||
|| (c >= 0xA0 && c <= 0xFE))
|
||||
{
|
||||
if (n <= 0)
|
||||
{ /* Fenceposts */
|
||||
|| (c >= 0xA0 && c <= 0xFE)) {
|
||||
if (n <= 0) { /* Fenceposts */
|
||||
lastflag = 0;
|
||||
return (n < 0 ? FALSE : TRUE);
|
||||
}
|
||||
@@ -286,14 +250,14 @@ int execute(int c, int f, int n)
|
||||
* Read in a key. Do the standard keyboard preprocessing. Convert the keys to
|
||||
* the internal character set.
|
||||
*/
|
||||
int getkey()
|
||||
int
|
||||
getkey(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = (*term.t_getchar) ();
|
||||
|
||||
if (c == METACH)
|
||||
{ /* Apply M- prefix */
|
||||
if (c == METACH) { /* Apply M- prefix */
|
||||
c = getctl();
|
||||
return (META | c);
|
||||
}
|
||||
@@ -305,7 +269,8 @@ int getkey()
|
||||
/*
|
||||
* Get a key. Apply control modifications to the read key.
|
||||
*/
|
||||
int getctl()
|
||||
int
|
||||
getctl()
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -317,41 +282,18 @@ int getctl()
|
||||
return (c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fancy quit command, as implemented by Norm. If any buffer has changed
|
||||
* do a write on that buffer and exit emacs, otherwise simply exit.
|
||||
*/
|
||||
int quickexit(int f, int n)
|
||||
{
|
||||
BUFFER *bp; /* scanning pointer to buffers */
|
||||
|
||||
bp = bheadp;
|
||||
while (bp != NULL)
|
||||
{
|
||||
if ((bp->b_flag & BFCHG) != 0 /* Changed */
|
||||
&& (bp->b_flag & BFTEMP) == 0)
|
||||
{ /* Real */
|
||||
curbp = bp; /* make that buffer current */
|
||||
mlwrite("[Saving %s]", (int*)bp->b_fname);
|
||||
filesave(f, n);
|
||||
}
|
||||
bp = bp->b_bufp; /* on to the next buffer */
|
||||
}
|
||||
return quit(f, n); /* conditionally quit */
|
||||
}
|
||||
|
||||
/*
|
||||
* Quit command. If an argument, always quit. Otherwise confirm if a buffer
|
||||
* has been changed and not written out. Normally bound to "C-X C-C".
|
||||
*/
|
||||
int quit(int f, int n)
|
||||
int
|
||||
quit(int f, int n)
|
||||
{
|
||||
int s;
|
||||
|
||||
if (f != FALSE /* Argument forces it */
|
||||
|| anycb() == FALSE /* All buffers clean */
|
||||
|| (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE)
|
||||
{
|
||||
|| (s = mlyesno("Quit without saving")) == TRUE) {
|
||||
vttidy();
|
||||
exit(0);
|
||||
}
|
||||
@@ -363,10 +305,10 @@ int quit(int f, int n)
|
||||
* Begin a keyboard macro. Error if not at the top level in keyboard
|
||||
* processing. Set up variables and return.
|
||||
*/
|
||||
int ctlxlp(int f, int n)
|
||||
{
|
||||
if (kbdmip != NULL || kbdmop != NULL)
|
||||
int
|
||||
ctlxlp(int f, int n)
|
||||
{
|
||||
if (kbdmip != NULL || kbdmop != NULL) {
|
||||
mlwrite("Not now");
|
||||
return (FALSE);
|
||||
}
|
||||
@@ -379,10 +321,10 @@ int ctlxlp(int f, int n)
|
||||
* End keyboard macro. Check for the same limit conditions as the above
|
||||
* routine. Set up the variables and return to the caller.
|
||||
*/
|
||||
int ctlxrp(int f, int n)
|
||||
{
|
||||
if (kbdmip == NULL)
|
||||
int
|
||||
ctlxrp(int f, int n)
|
||||
{
|
||||
if (kbdmip == NULL) {
|
||||
mlwrite("Not now");
|
||||
return (FALSE);
|
||||
}
|
||||
@@ -395,36 +337,31 @@ int ctlxrp(int f, int n)
|
||||
* Execute a macro. The command argument is the number of times to loop. Quit
|
||||
* as soon as a command gets an error. Return TRUE if all ok, else FALSE.
|
||||
*/
|
||||
int ctlxe(int f, int n)
|
||||
int
|
||||
ctlxe(int f, int n)
|
||||
{
|
||||
int c, af, an, s;
|
||||
|
||||
if (kbdmip != NULL || kbdmop != NULL)
|
||||
{
|
||||
if (kbdmip != NULL || kbdmop != NULL) {
|
||||
mlwrite("No macro defined");
|
||||
return (FALSE);
|
||||
}
|
||||
if (n <= 0)
|
||||
return (TRUE);
|
||||
do
|
||||
{
|
||||
do {
|
||||
kbdmop = &kbdm[0];
|
||||
do
|
||||
{
|
||||
do {
|
||||
af = FALSE;
|
||||
an = 1;
|
||||
if ((c = *kbdmop++) == (CTRL | 'U'))
|
||||
{
|
||||
if ((c = *kbdmop++) == (CTRL | 'U')) {
|
||||
af = TRUE;
|
||||
an = *kbdmop++;
|
||||
c = *kbdmop++;
|
||||
}
|
||||
s = TRUE;
|
||||
}
|
||||
while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
|
||||
} while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
|
||||
kbdmop = NULL;
|
||||
}
|
||||
while (s == TRUE && --n);
|
||||
} while (s == TRUE && --n);
|
||||
return (s);
|
||||
}
|
||||
|
||||
@@ -432,11 +369,11 @@ int ctlxe(int f, int n)
|
||||
* Abort. Beep the beeper. Kill off any keyboard macro, etc., that is in
|
||||
* progress. Sometimes called as a routine, to do general aborting of stuff.
|
||||
*/
|
||||
int ctrlg(int f, int n)
|
||||
int
|
||||
ctrlg(int f, int n)
|
||||
{
|
||||
(*term.t_beep) ();
|
||||
if (kbdmip != NULL)
|
||||
{
|
||||
if (kbdmip != NULL) {
|
||||
kbdm[0] = (CTLX | ')');
|
||||
kbdmip = NULL;
|
||||
}
|
||||
@@ -444,33 +381,6 @@ int ctrlg(int f, int n)
|
||||
return (ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle ANSI escape-extended commands (with "ESC [" or "ESC O" prefix)
|
||||
*/
|
||||
int extendedcmd(int f, int n)
|
||||
{
|
||||
int (*cmd)();
|
||||
int c;
|
||||
|
||||
c = getctl();
|
||||
switch (c)
|
||||
{
|
||||
case 'A': cmd = backline; break;
|
||||
case 'B': cmd = forwline; break;
|
||||
case 'C': cmd = forwchar; break;
|
||||
case 'D': cmd = backchar; break;
|
||||
case 'H': cmd = gotobob; break;
|
||||
case 'W': cmd = gotoeob; break;
|
||||
case '5': cmd = pageup; getctl(); break;
|
||||
case '6': cmd = pagedown; getctl(); break;
|
||||
case '7': cmd = gotobob; getctl(); break;
|
||||
case '8': cmd = gotoeob; getctl(); break;
|
||||
default: mlwrite("\007[Key not bound]");
|
||||
return (FALSE);
|
||||
}
|
||||
return cmd(f, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the version. All this does
|
||||
* is copy the version string into the echo line.
|
||||
@@ -480,6 +390,6 @@ int extendedcmd(int f, int n)
|
||||
int
|
||||
showversion(int f, int n)
|
||||
{
|
||||
mlwrite("emg 1.8");
|
||||
mlwrite("emg 2.0");
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
@@ -9,25 +9,25 @@
|
||||
#include "edef.h"
|
||||
|
||||
extern void mlwrite();
|
||||
extern void lchange(int flag);
|
||||
extern void lchange(int);
|
||||
extern int lnewline();
|
||||
extern int linsert(int n, int c);
|
||||
extern int backchar(int f, int n);
|
||||
extern int linsert(int, int);
|
||||
extern int backchar(int, int);
|
||||
extern void kdelete();
|
||||
extern int ldelete(int f, int n);
|
||||
extern int kremove(int k);
|
||||
extern int ldelete(int, int);
|
||||
extern int kremove(int);
|
||||
|
||||
int setfillcol(int f, int n);
|
||||
int getccol(int bflg);
|
||||
int twiddle(int f, int n);
|
||||
int quote(int f, int n);
|
||||
int tab(int f, int n);
|
||||
int openline(int f, int n);
|
||||
int newline(int f, int n);
|
||||
int forwdel(int f, int n);
|
||||
int backdel(int f, int n);
|
||||
int killtext(int f, int n);
|
||||
int yank(int f, int n);
|
||||
int setfillcol(int, int);
|
||||
int getccol(int);
|
||||
int twiddle(int, int);
|
||||
int quote(int, int);
|
||||
int tab(int, int);
|
||||
int openline(int, int);
|
||||
int newline(int, int);
|
||||
int forwdel(int, int);
|
||||
int backdel(int, int);
|
||||
int killtext(int, int);
|
||||
int yank(int, int);
|
||||
|
||||
/*
|
||||
* Set fill column to n.
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
#include "edef.h"
|
||||
|
||||
extern void kdelete();
|
||||
extern int ldelete(int f, int n);
|
||||
extern int kinsert(int c);
|
||||
extern int ldelete(int, int);
|
||||
extern int kinsert(int);
|
||||
extern void mlwrite();
|
||||
|
||||
int killregion(int f, int n);
|
||||
int copyregion(int f, int n);
|
||||
int getregion(REGION *rp);
|
||||
int killregion(int, int);
|
||||
int copyregion(int, int);
|
||||
int getregion(REGION *);
|
||||
|
||||
/*
|
||||
* Kill the region. Ask "getregion" to figure out the bounds of the region.
|
||||
|
||||
@@ -11,21 +11,21 @@
|
||||
#include "edef.h"
|
||||
|
||||
extern void mlwrite();
|
||||
extern int mlreplyt(char *prompt, char *buf, int nbuf, char eolchar);
|
||||
extern int mlreplyt(char *, char *, int, char);
|
||||
extern void update();
|
||||
extern int forwchar(int f, int n);
|
||||
extern int ldelete(int n, int kflag);
|
||||
extern int linsert(int n, int c);
|
||||
extern int forwchar(int, int);
|
||||
extern int ldelete(int, int);
|
||||
extern int linsert(int, int);
|
||||
|
||||
int forwsearch(int f, int n);
|
||||
int forwhunt(int f, int n);
|
||||
int backsearch(int f, int n);
|
||||
int backhunt(int f, int n);
|
||||
int bsearch(int f, int n);
|
||||
int eq(int bc, int pc);
|
||||
int readpattern(char *prompt);
|
||||
int forscan(char *patrn, int leavep);
|
||||
void expandp(char *srcstr, char *deststr, int maxlength);
|
||||
int forwsearch(int, int);
|
||||
int forwhunt(int, int);
|
||||
int backsearch(int, int);
|
||||
int backhunt(int, int);
|
||||
int bsearch(int, int);
|
||||
int eq(int, int);
|
||||
int readpattern(char *);
|
||||
int forscan(char *, int);
|
||||
void expandp(char *, char *, int);
|
||||
|
||||
#define PTBEG 1 /* leave the point at the begining on search */
|
||||
#define PTEND 2 /* leave the point at the end on search */
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
/* termios video driver */
|
||||
|
||||
#define termdef 1 /* don't define "term" externally */
|
||||
|
||||
#include <stdio.h> /* puts(3), snprintf(3) */
|
||||
|
||||
#include "estruct.h"
|
||||
#include "edef.h"
|
||||
#undef CTRL /* Needs to be done here. */
|
||||
@@ -22,15 +21,15 @@ extern void ttputc();
|
||||
extern void ttflush();
|
||||
extern void ttclose();
|
||||
|
||||
extern void panic();
|
||||
extern void panic(char *);
|
||||
|
||||
void getwinsize();
|
||||
void tcapopen();
|
||||
void tcapmove(int row, int col);
|
||||
void tcapeeol();
|
||||
void tcapeeop();
|
||||
void tcaprev();
|
||||
void tcapbeep();
|
||||
void getwinsize(void);
|
||||
void tcapopen(void);
|
||||
void tcapmove(int, int);
|
||||
void tcapeeol(void);
|
||||
void tcapeeop(void);
|
||||
void tcaprev(int);
|
||||
void tcapbeep(void);
|
||||
|
||||
#define MARGIN 8
|
||||
#define SCRSIZ 64
|
||||
@@ -45,25 +44,27 @@ TERM term = {
|
||||
ttflush, tcapmove, tcapeeol, tcapeeop, tcapbeep, tcaprev
|
||||
};
|
||||
|
||||
void getwinsize()
|
||||
void
|
||||
getwinsize(void)
|
||||
{
|
||||
int cols = COLS;
|
||||
int rows = ROWS;
|
||||
struct winsize ws;
|
||||
|
||||
/* Too small and we're out */
|
||||
if ((cols < 10) || (rows < 3))
|
||||
panic("Too few columns or rows");
|
||||
if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
|
||||
term.t_ncol = ws.ws_col;
|
||||
rows = ws.ws_row;
|
||||
}
|
||||
|
||||
if (COLS > MAXCOL)
|
||||
cols = MAXCOL;
|
||||
if (ROWS > MAXROW)
|
||||
rows = MAXROW;
|
||||
/* Too small and we hard code */
|
||||
if ((term.t_ncol < 10) || (rows < 3)) {
|
||||
term.t_ncol = 80;
|
||||
rows = 24;
|
||||
}
|
||||
|
||||
term.t_ncol = cols;
|
||||
term.t_nrow = rows - 1;
|
||||
}
|
||||
|
||||
void tcapopen()
|
||||
void
|
||||
tcapopen(void)
|
||||
{
|
||||
char tcbuf[1024];
|
||||
char *p, *tv_stype;
|
||||
@@ -90,28 +91,33 @@ void tcapopen()
|
||||
ttopen();
|
||||
}
|
||||
|
||||
void tcaprev(int state)
|
||||
void
|
||||
tcaprev(int state)
|
||||
{
|
||||
if (revexist)
|
||||
tputs((state ? SO : SE), 1, ttputc);
|
||||
}
|
||||
|
||||
void tcapmove (int row, int col)
|
||||
void
|
||||
tcapmove(int row, int col)
|
||||
{
|
||||
tputs(tgoto(CM, col, row), 1, ttputc);
|
||||
}
|
||||
|
||||
void tcapeeol()
|
||||
void
|
||||
tcapeeol(void)
|
||||
{
|
||||
tputs(CE, 1, ttputc);
|
||||
}
|
||||
|
||||
void tcapeeop()
|
||||
void
|
||||
tcapeeop(void)
|
||||
{
|
||||
tputs(CL, 1, ttputc);
|
||||
}
|
||||
|
||||
void tcapbeep()
|
||||
void
|
||||
tcapbeep(void)
|
||||
{
|
||||
ttputc(BEL);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
#include "estruct.h"
|
||||
#include "edef.h"
|
||||
|
||||
extern int backchar(int f, int n);
|
||||
extern int forwchar(int f, int n);
|
||||
extern int backchar(int, int);
|
||||
extern int forwchar(int, int);
|
||||
|
||||
int backword(int f, int n);
|
||||
int forwword(int f, int n);
|
||||
int backword(int, int);
|
||||
int forwword(int, int);
|
||||
int inword(void);
|
||||
|
||||
/*
|
||||
@@ -21,14 +21,14 @@ int inword(void);
|
||||
* performed by the "backchar" and "forwchar" routines. Error if you try to
|
||||
* move beyond the buffers
|
||||
*/
|
||||
int backword(int f, int n)
|
||||
int
|
||||
backword(int f, int n)
|
||||
{
|
||||
if (n < 0)
|
||||
return (forwword(f, -n));
|
||||
if (backchar(FALSE, 1) == FALSE)
|
||||
return (FALSE);
|
||||
while (n--)
|
||||
{
|
||||
while (n--) {
|
||||
while (inword() == FALSE)
|
||||
{
|
||||
if (backchar(FALSE, 1) == FALSE)
|
||||
@@ -47,12 +47,12 @@ int backword(int f, int n)
|
||||
* Move the cursor forward by the specified number of words. All of the motion
|
||||
* is done by "forwchar". Error if you try and move beyond the buffer's end
|
||||
*/
|
||||
int forwword(int f, int n)
|
||||
int
|
||||
forwword(int f, int n)
|
||||
{
|
||||
if (n < 0)
|
||||
return (backword(f, -n));
|
||||
while (n--)
|
||||
{
|
||||
while (n--) {
|
||||
while (inword() != FALSE)
|
||||
{
|
||||
if (forwchar(FALSE, 1) == FALSE)
|
||||
@@ -71,7 +71,8 @@ int forwword(int f, int n)
|
||||
* Return TRUE if the character at dot is a character that is considered to be
|
||||
* part of a word. The word character list is hard coded. Should be setable
|
||||
*/
|
||||
int inword(void)
|
||||
int
|
||||
inword(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
|
||||
@@ -1568,7 +1568,8 @@ int main (argc, argv)
|
||||
|
||||
if (! ofilfnd) {
|
||||
unlink ("a.out");
|
||||
link ("l.out", "a.out");
|
||||
if (link ("l.out", "a.out") < 0)
|
||||
perror("a.out");
|
||||
ofilename = "a.out";
|
||||
}
|
||||
delarg = errlev;
|
||||
|
||||
@@ -262,7 +262,7 @@ bad1: (void)lseek(rfd, (off_t)r_off, SEEK_SET);
|
||||
void symobj()
|
||||
{
|
||||
register RLIB *rp;
|
||||
char hb[sizeof(struct ar_hdr) + 1];
|
||||
char hb[sizeof(struct ar_hdr) + 1 + 64];
|
||||
long ransize, baseoff;
|
||||
|
||||
/* Rewind the archive, leaving the magic number. */
|
||||
@@ -385,7 +385,8 @@ int build()
|
||||
(void)lseek(tfd, (off_t)0, SEEK_SET);
|
||||
SETCF(tfd, tname, afd, archive, RPAD|WPAD);
|
||||
copy_ar(&cf, size);
|
||||
(void)ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR));
|
||||
if (ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR)) < 0)
|
||||
/* ignore */;
|
||||
(void)close(tfd);
|
||||
|
||||
/* Set the time. */
|
||||
|
||||
@@ -32,5 +32,5 @@ install: smlrc
|
||||
clean:
|
||||
rm -f *.o smlrc smlrc.dis smlrc.elf
|
||||
###
|
||||
smlrc.o: smlrc.c cgmips.c
|
||||
smlrc.o: smlrc.c fp.c cgmips.c
|
||||
${CC} ${CFLAGS} -mips16 smlrc.c -c -o $@
|
||||
|
||||
@@ -546,6 +546,11 @@ void GenFxnProlog(void)
|
||||
int i, cnt = CurFxnParamCntMax;
|
||||
if (cnt > 4)
|
||||
cnt = 4;
|
||||
// TBD!!! for structure passing use the cumulative parameter size
|
||||
// instead of the number of parameters. Currently this bug is masked
|
||||
// by the subroutine that pushes structures on the stack (it copies
|
||||
// all words except the first to the stack). But passing structures
|
||||
// in registers from assembly code won't always work.
|
||||
for (i = 0; i < cnt; i++)
|
||||
GenPrintInstr2Operands(MipsInstrSW, 0,
|
||||
MipsOpRegA0 + i, 0,
|
||||
|
||||
323
src/cmd/smlrc/fp.c
Normal file
323
src/cmd/smlrc/fp.c
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
Copyright (c) 2016, Alexey Frunze
|
||||
2-clause BSD license.
|
||||
*/
|
||||
|
||||
// This file implements the basic arithmetic functions on floats and
|
||||
// expects that the host representation of floats coinsides with the
|
||||
// target representation of floats and is IEEE 754 single precision.
|
||||
// It is also expected that the host implementation does not raise
|
||||
// any signals nor results in undefined behavior when handling
|
||||
// special cases involving infinities, NaNs and denormal numbers.
|
||||
|
||||
// Make sure float and int are the same size, so they can be
|
||||
// copied one into another byte by byte with memcpy().
|
||||
extern char StAtIcAsSeRt[(sizeof(float) == sizeof(unsigned)) ? 1 : -1];
|
||||
|
||||
// There can be up to 112 significant digits in a 32-bit single precision
|
||||
// floating point number (in the maximum positive denormal number).
|
||||
// We'll ignore any following digits, but convert these 112 with proper
|
||||
// rounding to even, which is enough for all floats representable exactly,
|
||||
// which should be enough for most practical purposes.
|
||||
#define MAX_CONST_DIGITS 112 // must be big enough for decimal/octal ints as well
|
||||
unsigned char ConstDigits[MAX_CONST_DIGITS];
|
||||
#define FP_MANT_BITS 23 // bits in mantissa, excluding the implicit 1
|
||||
#define FP_EXP_BITS 8 // bits in exponent
|
||||
#define FP_MIN_EXP (-46) // from min denormal, ~1.40e-45
|
||||
// (-46 is chosen because we need to handle numbers
|
||||
// like 9e-46 which round up to a non-zero denormal
|
||||
// number ~1.40e-45)
|
||||
#define FP_MAX_EXP 38 // from max normal, ~3.40e+38
|
||||
#define FP_BUF_SIZE (((((MAX_CONST_DIGITS-FP_MIN_EXP)*10+2)/3+FP_MANT_BITS+2)+7)/8)
|
||||
unsigned char ConstBinDigits[FP_BUF_SIZE];
|
||||
|
||||
STATIC
|
||||
unsigned f2u(unsigned f)
|
||||
{
|
||||
float ff;
|
||||
memcpy(&ff, &f, sizeof ff);
|
||||
if (ff != ff || ff <= -1.0f || ff >= (float)0x10000*0x10000/* 2**32 */)
|
||||
{
|
||||
warnFloat2Int();
|
||||
ff = 0;
|
||||
}
|
||||
return ff;
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned f2i(unsigned f, int opsz)
|
||||
{
|
||||
float ff;
|
||||
int ovf = 0;
|
||||
memcpy(&ff, &f, sizeof ff);
|
||||
if (ff != ff)
|
||||
{
|
||||
ovf = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (opsz)
|
||||
{
|
||||
case 1: // unsigned char
|
||||
ovf = ff <= -1.0f || ff >= 256.0f;
|
||||
break;
|
||||
case 2: // unsigned short
|
||||
ovf = ff <= -1.0f || ff >= 65536.0f;
|
||||
break;
|
||||
case -1: // signed char
|
||||
ovf = ff <= -129.0f || ff >= 128.0f;
|
||||
break;
|
||||
case -2: // signed short
|
||||
ovf = ff <= -32769.0f || ff >= 32768.0f;
|
||||
break;
|
||||
default: // signed int
|
||||
ovf = ff < -(float)0x8000*0x10000/* -2**31 */ || ff >= (float)0x8000*0x10000/* 2**31 */;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ovf)
|
||||
{
|
||||
warnFloat2Int();
|
||||
ff = 0;
|
||||
}
|
||||
return (int)ff;
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned u2f(unsigned i)
|
||||
{
|
||||
float f = i;
|
||||
memcpy(&i, &f, sizeof i);
|
||||
return i;
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned i2f(unsigned i)
|
||||
{
|
||||
float f = (int)i;
|
||||
memcpy(&i, &f, sizeof i);
|
||||
return i;
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned fneg(unsigned f)
|
||||
{
|
||||
float ff;
|
||||
memcpy(&ff, &f, sizeof ff);
|
||||
ff = -ff;
|
||||
memcpy(&f, &ff, sizeof f);
|
||||
return f;
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned fadd(unsigned fa, unsigned fb)
|
||||
{
|
||||
float ffa, ffb;
|
||||
memcpy(&ffa, &fa, sizeof ffa);
|
||||
memcpy(&ffb, &fb, sizeof ffb);
|
||||
ffa = ffa + ffb;
|
||||
memcpy(&fa, &ffa, sizeof fa);
|
||||
return fa;
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned fsub(unsigned fa, unsigned fb)
|
||||
{
|
||||
return fadd(fa, fneg(fb));
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned fmul(unsigned fa, unsigned fb)
|
||||
{
|
||||
float ffa, ffb;
|
||||
memcpy(&ffa, &fa, sizeof ffa);
|
||||
memcpy(&ffb, &fb, sizeof ffb);
|
||||
ffa = ffa * ffb;
|
||||
memcpy(&fa, &ffa, sizeof fa);
|
||||
return fa;
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned fdiv(unsigned fa, unsigned fb)
|
||||
{
|
||||
float ffa, ffb;
|
||||
memcpy(&ffa, &fa, sizeof ffa);
|
||||
memcpy(&ffb, &fb, sizeof ffb);
|
||||
ffa = ffa / ffb;
|
||||
memcpy(&fa, &ffa, sizeof fa);
|
||||
return fa;
|
||||
}
|
||||
|
||||
STATIC
|
||||
int fcmp(unsigned fa, unsigned fb, int nanRes)
|
||||
{
|
||||
float ffa, ffb;
|
||||
memcpy(&ffa, &fa, sizeof ffa);
|
||||
memcpy(&ffb, &fb, sizeof ffb);
|
||||
if (ffa != ffa || ffb != ffb)
|
||||
return nanRes;
|
||||
if (ffa < ffb)
|
||||
return -1;
|
||||
if (ffa > ffb)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC
|
||||
void ChainMultiplyAdd(unsigned char* pChain,
|
||||
unsigned ChainLen,
|
||||
unsigned char Multiplier,
|
||||
unsigned char Addend)
|
||||
{
|
||||
unsigned carry = Addend;
|
||||
|
||||
while (ChainLen--)
|
||||
{
|
||||
carry += *pChain * Multiplier;
|
||||
*pChain++ = carry & 0xFFu;
|
||||
carry >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void ChainDivide(unsigned char* pChain,
|
||||
unsigned ChainLen,
|
||||
unsigned char Divisor,
|
||||
unsigned char* pRemainder)
|
||||
{
|
||||
unsigned remainder = 0;
|
||||
|
||||
while (ChainLen)
|
||||
{
|
||||
remainder += pChain[ChainLen - 1];
|
||||
pChain[ChainLen - 1] = remainder / Divisor;
|
||||
remainder = (remainder % Divisor) << 8;
|
||||
ChainLen--;
|
||||
}
|
||||
|
||||
if (pRemainder != NULL)
|
||||
*pRemainder = remainder >> 8;
|
||||
}
|
||||
|
||||
// Multiplies an integer (cnt decimal digits (0 to 9) from digits[]) by
|
||||
// 10**eexp, converts the product to a float and returns it as unsigned int.
|
||||
// This is an inefficient but straightforward algorithm with proper rounding.
|
||||
STATIC
|
||||
unsigned d2f(unsigned char* digits, int cnt, int eexp)
|
||||
{
|
||||
unsigned numDecDigits;
|
||||
unsigned denDecDigits;
|
||||
unsigned numBinDigits;
|
||||
unsigned numBytes;
|
||||
int tmp;
|
||||
unsigned char remainder;
|
||||
int binExp = 0;
|
||||
int inexact = 0;
|
||||
int lastInexact = 0;
|
||||
unsigned res;
|
||||
|
||||
// 0?
|
||||
if (cnt == 1 && *digits == 0)
|
||||
return 0;
|
||||
// less than the denormalized minimum?
|
||||
if (eexp < FP_MIN_EXP - (cnt - 1))
|
||||
return 0;
|
||||
|
||||
// greater than the normalized maximum?
|
||||
if (eexp > FP_MAX_EXP - (cnt - 1))
|
||||
return 0x7F800000; // +INF
|
||||
|
||||
numDecDigits = cnt + ((eexp >= 0) ? eexp : 0);
|
||||
denDecDigits = 1 + ((eexp < 0) ? -eexp : 0);
|
||||
|
||||
// 10/3=3.3(3) > log2(10)~=3.32
|
||||
if (eexp >= 0)
|
||||
{
|
||||
unsigned t1 = (numDecDigits * 10 + 2) / 3;
|
||||
unsigned t2 = FP_MANT_BITS + 1;
|
||||
numBinDigits = (t1 >= t2) ? t1 : t2;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned t1 = (numDecDigits * 10 + 2) / 3;
|
||||
unsigned t2 = (denDecDigits * 10 + 2) / 3 + FP_MANT_BITS + 1 + 1;
|
||||
numBinDigits = (t1 >= t2) ? t1 : t2;
|
||||
}
|
||||
|
||||
numBytes = (numBinDigits + 7) / 8;
|
||||
if (numBytes > (unsigned)FP_BUF_SIZE)
|
||||
errorInternal(200);
|
||||
memset(ConstBinDigits, 0, numBytes);
|
||||
|
||||
// Convert the numerator to binary
|
||||
for (tmp = 0; tmp < cnt; tmp++)
|
||||
ChainMultiplyAdd(ConstBinDigits, numBytes, 10, ConstDigits[tmp]);
|
||||
for (tmp = eexp; tmp > 0; tmp--)
|
||||
ChainMultiplyAdd(ConstBinDigits, numBytes, 10, 0);
|
||||
|
||||
// If the denominator isn't 1, divide the numerator by the denominator
|
||||
// getting at least FractionBitCnt+2 significant bits of quotient
|
||||
if (eexp < 0)
|
||||
{
|
||||
binExp = -(int)(numBinDigits - (numDecDigits * 10 + 2) / 3);
|
||||
for (tmp = binExp; tmp < 0; tmp++)
|
||||
ChainMultiplyAdd(ConstBinDigits, numBytes, 2, 0);
|
||||
for (tmp = eexp; tmp < 0; tmp++)
|
||||
ChainDivide(ConstBinDigits, numBytes, 10, &remainder),
|
||||
lastInexact = inexact, inexact |= !!remainder;
|
||||
}
|
||||
|
||||
// Find the most significant bit and normalize the mantissa
|
||||
// by shifting it left
|
||||
for (tmp = numBytes - 1; tmp >= 0 && !ConstBinDigits[tmp]; tmp--);
|
||||
if (tmp >= 0)
|
||||
{
|
||||
tmp = tmp * 8 + 7;
|
||||
while (!(ConstBinDigits[tmp / 8] & (1 << tmp % 8))) tmp--;
|
||||
while (tmp < FP_MANT_BITS)
|
||||
ChainMultiplyAdd(ConstBinDigits, numBytes, 2, 0), binExp--, tmp++;
|
||||
}
|
||||
|
||||
// Find the most significant bit and normalize the mantissa
|
||||
// by shifting it right
|
||||
do
|
||||
{
|
||||
remainder = 0;
|
||||
for (tmp = numBytes - 1; tmp >= 0 && !ConstBinDigits[tmp]; tmp--);
|
||||
if (tmp >= 0)
|
||||
{
|
||||
tmp = tmp * 8 + 7;
|
||||
while (!(ConstBinDigits[tmp / 8] & (1 << tmp % 8))) tmp--;
|
||||
while (tmp > FP_MANT_BITS)
|
||||
ChainDivide(ConstBinDigits, numBytes, 2, &remainder),
|
||||
lastInexact = inexact, inexact |= !!remainder, binExp++, tmp--;
|
||||
while (binExp < 2 - (1 << (FP_EXP_BITS - 1)) - FP_MANT_BITS)
|
||||
ChainDivide(ConstBinDigits, numBytes, 2, &remainder),
|
||||
lastInexact = inexact, inexact |= !!remainder, binExp++;
|
||||
}
|
||||
// Round to nearest even
|
||||
remainder &= (lastInexact | (ConstBinDigits[0] & 1));
|
||||
if (remainder)
|
||||
ChainMultiplyAdd(ConstBinDigits, numBytes, 1, 1);
|
||||
} while (remainder);
|
||||
|
||||
// Collect the result's mantissa
|
||||
res = 0;
|
||||
while (tmp >= 0)
|
||||
{
|
||||
res <<= 8;
|
||||
res |= ConstBinDigits[tmp / 8];
|
||||
tmp -= 8;
|
||||
}
|
||||
|
||||
// Collect the result's exponent
|
||||
binExp += (1 << (FP_EXP_BITS - 1)) - 1 + FP_MANT_BITS;
|
||||
if (!(res & (1u << FP_MANT_BITS))) binExp = 0; // subnormal or 0
|
||||
res &= ~(1u << FP_MANT_BITS);
|
||||
if (binExp >= (1 << FP_EXP_BITS) - 1)
|
||||
binExp = (1 << FP_EXP_BITS) - 1, res = 0, inexact |= 1; // +INF
|
||||
res |= (unsigned)binExp << FP_MANT_BITS;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2013-2015, Alexey Frunze
|
||||
Copyright (c) 2013-2016, Alexey Frunze
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -66,6 +66,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
extern int main(int argc, char** argv);
|
||||
void exit(int);
|
||||
|
||||
#ifdef __SMALLER_C_32__
|
||||
extern void __x87init(void);
|
||||
#endif
|
||||
|
||||
#ifdef _RETROBSD
|
||||
void __start__(int argc, char** argv)
|
||||
{
|
||||
@@ -75,6 +79,7 @@ void __start__(int argc, char** argv)
|
||||
#ifdef _LINUX
|
||||
void __start__(int argc, char** argv)
|
||||
{
|
||||
__x87init();
|
||||
exit(main(argc, argv));
|
||||
}
|
||||
#else
|
||||
@@ -85,6 +90,9 @@ void __start__(void)
|
||||
int argc;
|
||||
char** argv;
|
||||
__setargs__(&argc, &argv);
|
||||
#ifdef __SMALLER_C_32__
|
||||
__x87init();
|
||||
#endif
|
||||
exit(main(argc, argv));
|
||||
}
|
||||
#endif
|
||||
@@ -371,6 +379,22 @@ void* memset(void* s, int c, unsigned n)
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef __SMALLER_C_32__
|
||||
int memcmp(void* s1, void* s2, unsigned n)
|
||||
{
|
||||
if (n)
|
||||
{
|
||||
unsigned char *p1 = s1, *p2 = s2;
|
||||
do
|
||||
{
|
||||
if (*p1++ != *p2++)
|
||||
return (*--p1 - *--p2);
|
||||
} while (--n);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int fputc(int c, FILE* stream);
|
||||
int putchar(int c);
|
||||
|
||||
@@ -1548,4 +1572,187 @@ int fsetpos(FILE* stream, fpos_t* pos)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __SMALLER_C_32__
|
||||
#ifndef _RETROBSD
|
||||
|
||||
#ifdef __HUGE__
|
||||
#define xbp "bp"
|
||||
#define xsp "sp"
|
||||
#else
|
||||
#define xbp "ebp"
|
||||
#define xsp "esp"
|
||||
#endif
|
||||
|
||||
void __x87init(void)
|
||||
{
|
||||
// Mask all exceptions, set rounding to nearest even and precision to 64 bits.
|
||||
// TBD??? Actually check for x87???
|
||||
asm("fninit");
|
||||
}
|
||||
|
||||
float __floatsisf(int i)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"fild dword ["xbp"+8]\n"
|
||||
"fstp dword ["xbp"+8]\n"
|
||||
"mov eax, ["xbp"+8]"
|
||||
);
|
||||
}
|
||||
|
||||
float __floatunsisf(unsigned i)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"push dword 0\n"
|
||||
"push dword ["xbp"+8]\n"
|
||||
"fild qword ["xbp"-8]\n" // load 32-bit unsigned int as 64-bit signed int
|
||||
"add "xsp", 8\n"
|
||||
"fstp dword ["xbp"+8]\n"
|
||||
"mov eax, ["xbp"+8]"
|
||||
);
|
||||
}
|
||||
|
||||
int __fixsfsi(float f)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"sub "xsp", 4\n"
|
||||
"fnstcw ["xbp"-2]\n" // save rounding
|
||||
"mov ax, ["xbp"-2]\n"
|
||||
"mov ah, 0x0c\n" // rounding towards 0 (AKA truncate) since we don't have fisttp
|
||||
"mov ["xbp"-4], ax\n"
|
||||
"fld dword ["xbp"+8]\n"
|
||||
"fldcw ["xbp"-4]\n" // rounding = truncation
|
||||
"fistp dword ["xbp"+8]\n"
|
||||
"fldcw ["xbp"-2]\n" // restore rounding
|
||||
"add "xsp", 4\n"
|
||||
"mov eax, ["xbp"+8]"
|
||||
);
|
||||
}
|
||||
|
||||
unsigned __fixunssfsi(float f)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"sub "xsp", 12\n"
|
||||
"fnstcw ["xbp"-2]\n" // save rounding
|
||||
"mov ax, ["xbp"-2]\n"
|
||||
"mov ah, 0x0c\n" // rounding towards 0 (AKA truncate) since we don't have fisttp
|
||||
"mov ["xbp"-4], ax\n"
|
||||
"fld dword ["xbp"+8]\n"
|
||||
"fldcw ["xbp"-4]\n" // rounding = truncation
|
||||
"fistp qword ["xbp"-12]\n" // store 64-bit signed int
|
||||
"fldcw ["xbp"-2]\n" // restore rounding
|
||||
"mov eax, ["xbp"-12]\n" // take low 32 bits
|
||||
"add "xsp", 12"
|
||||
);
|
||||
}
|
||||
|
||||
float __addsf3(float a, float b)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"fld dword ["xbp"+8]\n"
|
||||
"fadd dword ["xbp"+12]\n"
|
||||
"fstp dword ["xbp"+8]\n"
|
||||
"mov eax, ["xbp"+8]"
|
||||
);
|
||||
}
|
||||
|
||||
float __subsf3(float a, float b)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"fld dword ["xbp"+8]\n"
|
||||
"fsub dword ["xbp"+12]\n"
|
||||
"fstp dword ["xbp"+8]\n"
|
||||
"mov eax, ["xbp"+8]"
|
||||
);
|
||||
}
|
||||
|
||||
float __negsf2(float f)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"mov eax, ["xbp"+8]\n"
|
||||
"xor eax, 0x80000000"
|
||||
);
|
||||
}
|
||||
|
||||
float __mulsf3(float a, float b)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"fld dword ["xbp"+8]\n"
|
||||
"fmul dword ["xbp"+12]\n"
|
||||
"fstp dword ["xbp"+8]\n"
|
||||
"mov eax, ["xbp"+8]"
|
||||
);
|
||||
}
|
||||
|
||||
float __divsf3(float a, float b)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"fld dword ["xbp"+8]\n"
|
||||
"fdiv dword ["xbp"+12]\n"
|
||||
"fstp dword ["xbp"+8]\n"
|
||||
"mov eax, ["xbp"+8]"
|
||||
);
|
||||
}
|
||||
|
||||
float __lesf2(float a, float b)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"fld dword ["xbp"+12]\n"
|
||||
"fld dword ["xbp"+8]\n"
|
||||
"fucompp\n"
|
||||
"fstsw ax\n" // must use these moves since we don't have fucomip
|
||||
"sahf\n"
|
||||
"jnp .ordered\n"
|
||||
"mov eax, +1\n" // return +1 if either a or b (or both) is a NaN
|
||||
"jmp .done\n"
|
||||
".ordered:\n"
|
||||
"jnz .unequal\n"
|
||||
"xor eax, eax\n" // return 0 if a == b
|
||||
"jmp .done\n"
|
||||
".unequal:\n"
|
||||
"sbb eax, eax\n"
|
||||
"jc .done\n" // return -1 if a < b
|
||||
"inc eax\n" // return +1 if a > b
|
||||
".done:"
|
||||
);
|
||||
}
|
||||
|
||||
float __gesf2(float a, float b)
|
||||
{
|
||||
asm
|
||||
(
|
||||
"fld dword ["xbp"+12]\n"
|
||||
"fld dword ["xbp"+8]\n"
|
||||
"fucompp\n"
|
||||
"fstsw ax\n" // must use these moves since we don't have fucomip
|
||||
"sahf\n"
|
||||
"jnp .ordered\n"
|
||||
"mov eax, -1\n" // return -1 if either a or b (or both) is a NaN
|
||||
"jmp .done\n"
|
||||
".ordered:\n"
|
||||
"jnz .unequal\n"
|
||||
"xor eax, eax\n" // return 0 if a == b
|
||||
"jmp .done\n"
|
||||
".unequal:\n"
|
||||
"sbb eax, eax\n"
|
||||
"jc .done\n" // return -1 if a < b
|
||||
"inc eax\n" // return +1 if a > b
|
||||
".done:"
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /*__APPLE__*/
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/termios.h>
|
||||
#include <termios.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -50,7 +50,8 @@ strip(name)
|
||||
head.a_reldata = 0;
|
||||
head.a_syms = 0;
|
||||
(void) lseek(f, (off_t)0, SEEK_SET);
|
||||
(void) write(f, (char *)&head, sizeof (head));
|
||||
if (write(f, (char *)&head, sizeof (head)) != sizeof (head))
|
||||
/* ignore */;
|
||||
out:
|
||||
close(f);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ OPTON = -O2 -fomit-frame-pointer -fforce-addr -ffast-math -Wall
|
||||
#CFLAGS = -DTIME -std1 -verbose -w0
|
||||
|
||||
## generic gcc CFLAGS. -DTIME must be included
|
||||
CFLAGS = -DTIME -Wall -pedantic -ansi
|
||||
#CFLAGS = -DTIME -Wall -pedantic -ansi
|
||||
|
||||
# local directories
|
||||
PROGDIR = ./pgms
|
||||
|
||||
@@ -67,7 +67,6 @@ char *vi_Version =
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
@@ -81,12 +80,17 @@ char *vi_Version =
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
//#include <err.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lib/last_char_is.c"
|
||||
#if defined(linux) || defined(__APPLE__)
|
||||
# include <termios.h>
|
||||
# include <err.h>
|
||||
#else
|
||||
# include "lib/strlcat.c"
|
||||
# include "lib/strlcpy.c"
|
||||
# define termios sgttyb
|
||||
#endif
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
@@ -96,7 +100,6 @@ char *vi_Version =
|
||||
#endif /* TRUE */
|
||||
#define MAX_SCR_COLS BUFSIZ
|
||||
#define BUFSIZ_STATBUF 200
|
||||
#define termios sgttyb
|
||||
|
||||
// Misc. non-Ascii keys that report an escape sequence
|
||||
#define VI_K_UP 128 // cursor key Up
|
||||
@@ -1789,7 +1792,8 @@ static void colon(Byte * buf)
|
||||
while (isblnk(*buf))
|
||||
buf++;
|
||||
/* FIXED strcpy((char *) args, (char *) buf); */
|
||||
if (strlcpy((char *) args, (char *) buf, sizeof((char *)args)) > sizeof((char *)args)) err(1, "strlcpy overflow in function colon");
|
||||
if (strlcpy((char *) args, (char *) buf, sizeof(args)) > sizeof(args))
|
||||
err(1, "strlcpy overflow in function colon");
|
||||
buf1 = (Byte *)last_char_is((char *)cmd, '!');
|
||||
if (buf1) {
|
||||
useforce = TRUE;
|
||||
@@ -3183,7 +3187,7 @@ static int isblnk(Byte c) // is the char a blank or tab
|
||||
//----- Set terminal attributes --------------------------------
|
||||
static void rawmode(void)
|
||||
{
|
||||
#if 0
|
||||
#ifdef TCSANOW
|
||||
tcgetattr(0, &term_orig);
|
||||
term_vi = term_orig;
|
||||
term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG ON- allow intr's
|
||||
@@ -3208,7 +3212,7 @@ static void rawmode(void)
|
||||
|
||||
static void cookmode(void)
|
||||
{
|
||||
#if 0
|
||||
#ifdef TCSANOW
|
||||
tcsetattr(0, TCSANOW, &term_orig);
|
||||
#else
|
||||
ioctl(0, TIOCSETP, &term_orig);
|
||||
|
||||
1
src/cmd/yacc/.gitignore
vendored
Normal file
1
src/cmd/yacc/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
yacc
|
||||
@@ -1,24 +1,31 @@
|
||||
#
|
||||
# @(#)Makefile 4.2.1 (2.11BSD) 1996/10/24
|
||||
#
|
||||
DESTDIR=
|
||||
SEPFLAG= -i
|
||||
CFLAGS=-O
|
||||
SRCS = Makefile dextern files yaccpar \
|
||||
y1.c y2.c y3.c y4.c \
|
||||
yaccdiffs yaccnews
|
||||
#==========================================
|
||||
# Makefile: makefile for yacc
|
||||
# Copyright 2012 Majenko Technolohies
|
||||
# (matt@majenko.co.uk
|
||||
# Last Modified: 29/01/2012
|
||||
#==========================================
|
||||
|
||||
TOPSRC = $(shell cd ../../..; pwd)
|
||||
include $(TOPSRC)/target.mk
|
||||
|
||||
OBJS = y1.o y2.o y3.o y4.o
|
||||
SRCS = y1.c y2.c y3.c y4.c
|
||||
|
||||
all: yacc
|
||||
|
||||
yacc: y1.o y2.o y3.o y4.o
|
||||
$(CC) ${SEPFLAG} -o yacc y?.o
|
||||
y1.o y2.o y3.o y4.o: dextern files
|
||||
install: yacc yaccpar
|
||||
install -s yacc $(DESTDIR)/usr/bin
|
||||
install -c yaccpar $(DESTDIR)/usr/share/misc
|
||||
clean :
|
||||
-rm -f *.o yacc
|
||||
yacc: ${OBJS}
|
||||
${CC} ${LDFLAGS} -o yacc.elf ${OBJS} ${LIBS}
|
||||
${OBJDUMP} -S yacc.elf > yacc.dis
|
||||
${SIZE} yacc.elf
|
||||
${ELF2AOUT} yacc.elf $@
|
||||
|
||||
srcs: $(SRCS)
|
||||
$(SRCS):
|
||||
sccs get $@
|
||||
clean:
|
||||
-rm -f yacc ${OBJS} yacc.elf yacc.dis
|
||||
|
||||
install: all
|
||||
install yacc $(DESTDIR)/bin/
|
||||
|
||||
y1.o: y1.c dextern
|
||||
y2.o: y2.c dextern
|
||||
y3.o: y3.c dextern
|
||||
y4.o: y4.c dextern
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
# ifdef MEDIUM
|
||||
# define ACTSIZE 4000
|
||||
# define MEMSIZE 5200
|
||||
# define NSTATES 600
|
||||
# define NSTATES 750
|
||||
# define NTERMS 127
|
||||
# define NPROD 400
|
||||
# define NNONTERM 200
|
||||
@@ -43,6 +43,19 @@
|
||||
# define WSETSIZE 250
|
||||
# endif
|
||||
|
||||
# ifdef TINY
|
||||
# define ACTSIZE 1000
|
||||
# define MEMSIZE 1300
|
||||
# define NSTATES 750
|
||||
# define NTERMS 127
|
||||
# define NPROD 200
|
||||
# define NNONTERM 50
|
||||
# define TEMPSIZE 200
|
||||
# define CNAMSZ 1000
|
||||
# define LSETSIZE 250
|
||||
# define WSETSIZE 100
|
||||
# endif
|
||||
|
||||
# define NAMESIZE 50
|
||||
# define NTYPES 63
|
||||
|
||||
|
||||
@@ -17,4 +17,5 @@
|
||||
|
||||
/* basic size of the Yacc implementation */
|
||||
/* # define HUGE */
|
||||
#define MEDIUM
|
||||
/* #define MEDIUM */
|
||||
#define TINY
|
||||
|
||||
@@ -3,6 +3,7 @@ static char sccsid[] = "@(#)y1.c 4.1.1 (2.11BSD) 1995/05/11";
|
||||
#endif
|
||||
|
||||
# include "dextern"
|
||||
#include <stdlib.h>
|
||||
|
||||
/* variables used locally */
|
||||
|
||||
|
||||
@@ -3,18 +3,19 @@
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
||||
"elf32-littlemips")
|
||||
OUTPUT_ARCH(mips)
|
||||
OUTPUT_ARCH(pic32mx)
|
||||
ENTRY(_start)
|
||||
|
||||
/* Required by Microchip C32 linker */
|
||||
/*MEMORY
|
||||
MEMORY
|
||||
{
|
||||
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x80000
|
||||
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
|
||||
exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
|
||||
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490
|
||||
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 512K
|
||||
exception_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x1000
|
||||
kseg0_boot_mem (rx) : ORIGIN = 0x9FC00000, LENGTH = 12K-16
|
||||
kseg1_boot_mem (rx) : ORIGIN = 0xBFC00000, LENGTH = 0x490
|
||||
kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x20000
|
||||
}*/
|
||||
}
|
||||
_min_heap_size = 0;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
1
src/games/.gitignore
vendored
1
src/games/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
aclock
|
||||
arithmetic
|
||||
banner
|
||||
bcd
|
||||
|
||||
@@ -18,7 +18,7 @@ SUBDIR = adventure atc backgammon battlestar boggle btlgammon \
|
||||
# C programs that live in the current directory and do not need
|
||||
# explicit make lines.
|
||||
#
|
||||
STD = banner arithmetic bcd cfscores factor fish morse \
|
||||
STD = banner aclock arithmetic bcd cfscores factor fish morse \
|
||||
number ppt wump
|
||||
|
||||
# C programs that live in the current directory and need explicit make lines.
|
||||
|
||||
175
src/games/aclock.c
Normal file
175
src/games/aclock.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* aclock - ascii clock for UNIX Console
|
||||
*
|
||||
* Copyright (c) 1994-2013 Antoni Sawicki <as@tenoware.com>
|
||||
* Version 2.3 (unix-termcap); Mountain View, July 2013
|
||||
*
|
||||
* Ported to RetroBSD by Serge Vakulenko
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#define FontWH_Ratio 2
|
||||
|
||||
void cls(void)
|
||||
{
|
||||
printf("\33[2J");
|
||||
}
|
||||
|
||||
void draw_point(int x, int y, char c)
|
||||
{
|
||||
printf("\33[%u;%uH%c", y+1, x+1, c);
|
||||
}
|
||||
|
||||
void draw_text(int x, int y, char *string)
|
||||
{
|
||||
printf("\33[%u;%uH%s", y+1, x+1, string);
|
||||
}
|
||||
|
||||
int icos(int n, int maxval)
|
||||
{
|
||||
static const int tab[] = {
|
||||
1000000000, 994521895, 978147600, 951056516, 913545457,
|
||||
866025403, 809016994, 743144825, 669130606, 587785252,
|
||||
500000000, 406736643, 309016994, 207911690, 104528463,
|
||||
0, -104528463, -207911690, -309016994, -406736643,
|
||||
-499999999, -587785252, -669130606, -743144825, -809016994,
|
||||
-866025403, -913545457, -951056516, -978147600, -994521895,
|
||||
-1000000000, -994521895, -978147600, -951056516, -913545457,
|
||||
-866025403, -809016994, -743144825, -669130606, -587785252,
|
||||
-500000000, -406736643, -309016994, -207911690, -104528463,
|
||||
0, 104528463, 207911690, 309016994, 406736643,
|
||||
500000000, 587785252, 669130606, 743144825, 809016994,
|
||||
866025403, 913545457, 951056516, 978147600, 994521895,
|
||||
};
|
||||
if (n < 0)
|
||||
n += 60;
|
||||
return tab[n%60] / 1000 * maxval / 1000000;
|
||||
}
|
||||
|
||||
int isin(int n, int maxval)
|
||||
{
|
||||
static const int tab[] = {
|
||||
0, 104528463, 207911690, 309016994, 406736643,
|
||||
499999999, 587785252, 669130606, 743144825, 809016994,
|
||||
866025403, 913545457, 951056516, 978147600, 994521895,
|
||||
1000000000, 994521895, 978147600, 951056516, 913545457,
|
||||
866025403, 809016994, 743144825, 669130606, 587785252,
|
||||
499999999, 406736643, 309016994, 207911690, 104528463,
|
||||
0, -104528463, -207911690, -309016994, -406736643,
|
||||
-500000000, -587785252, -669130606, -743144825, -809016994,
|
||||
-866025403, -913545457, -951056516, -978147600, -994521895,
|
||||
-1000000000,-994521895, -978147600, -951056516, -913545457,
|
||||
-866025403, -809016994, -743144825, -669130606, -587785252,
|
||||
-499999999, -406736643, -309016994, -207911690, -104528463,
|
||||
};
|
||||
if (n < 0)
|
||||
n += 60;
|
||||
return tab[n%60] / 1000 * maxval / 1000000;
|
||||
}
|
||||
|
||||
void draw_circle(int hand_max, int sYcen, int sXcen)
|
||||
{
|
||||
int x, y, r;
|
||||
char c;
|
||||
|
||||
for (r=0; r<60; r++) {
|
||||
x = icos(r, hand_max) * FontWH_Ratio + sXcen;
|
||||
y = isin(r, hand_max) + sYcen;
|
||||
switch (r) {
|
||||
case 0:
|
||||
case 5:
|
||||
case 10:
|
||||
case 15:
|
||||
case 20:
|
||||
case 25:
|
||||
case 30:
|
||||
case 35:
|
||||
case 40:
|
||||
case 45:
|
||||
case 50:
|
||||
case 55:
|
||||
c='o';
|
||||
break;
|
||||
default:
|
||||
c='.';
|
||||
break;
|
||||
}
|
||||
draw_point(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_hand(int minute, int hlength, char c, int sXcen, int sYcen)
|
||||
{
|
||||
int x, y, n;
|
||||
|
||||
for (n=1; n<hlength; n++) {
|
||||
x = icos(minute - 15, n) * FontWH_Ratio + sXcen;
|
||||
y = isin(minute - 15, n) + sYcen;
|
||||
draw_point(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char digital_time[32];
|
||||
int sXmax, sYmax, sXmaxo, sYmaxo, smax, hand_max, sXcen, sYcen;
|
||||
time_t t;
|
||||
struct tm *ltime;
|
||||
struct winsize ws;
|
||||
|
||||
sXmaxo = sYmaxo = sXmax = sYmax = 0;
|
||||
sXcen = sYcen = 0;
|
||||
hand_max = 0;
|
||||
|
||||
while (1) {
|
||||
sXmaxo = sXmax;
|
||||
sYmaxo = sYmax;
|
||||
|
||||
ioctl(1, TIOCGWINSZ, &ws);
|
||||
|
||||
sXmax = ws.ws_col;
|
||||
if (sXmax == 0)
|
||||
sXmax = 80;
|
||||
sYmax = ws.ws_row;
|
||||
if (sYmax == 0)
|
||||
sYmax = 24;
|
||||
|
||||
if (sXmax != sXmaxo || sYmax != sYmaxo) {
|
||||
if (sXmax/2 <= sYmax)
|
||||
smax = sXmax/2;
|
||||
else
|
||||
smax = sYmax;
|
||||
|
||||
hand_max = (smax/2)-1;
|
||||
|
||||
sXcen = sXmax/2;
|
||||
sYcen = sYmax/2;
|
||||
|
||||
cls();
|
||||
draw_circle(hand_max, sYcen, sXcen);
|
||||
}
|
||||
|
||||
time(&t);
|
||||
ltime = localtime(&t);
|
||||
|
||||
draw_hand((ltime->tm_hour*5) + (ltime->tm_min/10), 2*hand_max/3, 'h', sXcen, sYcen);
|
||||
draw_hand(ltime->tm_min, hand_max-2, 'm', sXcen, sYcen);
|
||||
draw_hand(ltime->tm_sec, hand_max-1, '.', sXcen, sYcen);
|
||||
|
||||
draw_text(sXcen - 4, sYcen - (3*hand_max/5), "RetroBSD");
|
||||
sprintf(digital_time, "[%02d:%02d:%02d]", ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
|
||||
draw_text(sXcen - 5, sYcen + (3*hand_max/5), digital_time);
|
||||
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
|
||||
draw_hand((ltime->tm_hour*5) + (ltime->tm_min/10), 2*hand_max/3, ' ', sXcen, sYcen);
|
||||
draw_hand(ltime->tm_min, hand_max-2, ' ', sXcen, sYcen);
|
||||
draw_hand(ltime->tm_sec, hand_max-1, ' ', sXcen, sYcen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ TOPSRC = $(shell cd ../../..; pwd)
|
||||
include $(TOPSRC)/target.mk
|
||||
#include $(TOPSRC)/cross.mk
|
||||
|
||||
CFLAGS = -Os -g -Werror -Wall
|
||||
CFLAGS += -Os -g -Werror -Wall
|
||||
CFLAGS += -DBSD -DDEST=\"/games/lib/atc/\"
|
||||
#CFLAGS += -DSYSV -DDEST=\"games/\"
|
||||
YFLAGS = -d
|
||||
|
||||
@@ -4,16 +4,27 @@
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* BIG = 2**(DBL_MANT_DIG+3) defines how many decimal digits
|
||||
* to take into account from the input. It doesn't make sense
|
||||
* to use more digits than log10(2**DBL_MANT_DIG)+1.
|
||||
* BIG is equal 2**27 or 2**56, depending on whether double
|
||||
* is single or double precision.
|
||||
*/
|
||||
#define BIG (8 * (double)(1L << (DBL_MANT_DIG/2)) * \
|
||||
(double)(1L << (DBL_MANT_DIG/2 + DBL_MANT_DIG%2)))
|
||||
|
||||
double
|
||||
atof(p)
|
||||
register char *p;
|
||||
{
|
||||
register int c;
|
||||
double fl, flexp, exp5;
|
||||
double big = 72057594037927936.; /*2^56*/
|
||||
double big = BIG;
|
||||
int nd;
|
||||
register int eexp, exp, neg, negexp, bexp;
|
||||
|
||||
@@ -73,7 +84,7 @@ register char *p;
|
||||
}
|
||||
|
||||
|
||||
if ((nd+exp*negexp) < -LOGHUGE){
|
||||
if ((nd+exp*negexp) < DBL_MIN_10_EXP - 2) {
|
||||
fl = 0;
|
||||
exp = 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
double
|
||||
@@ -5,10 +6,11 @@ ldexp(fr, exp)
|
||||
double fr;
|
||||
int exp;
|
||||
{
|
||||
double huge = 1.701411834604692293e38;
|
||||
int neg;
|
||||
int i;
|
||||
|
||||
if (fr == 0)
|
||||
return 0;
|
||||
neg = 0;
|
||||
if (fr < 0) {
|
||||
fr = -fr;
|
||||
@@ -20,13 +22,13 @@ ldexp(fr, exp)
|
||||
i = i-1;
|
||||
}
|
||||
exp = exp+i;
|
||||
if (exp > 127) {
|
||||
if (exp >= DBL_MAX_EXP) {
|
||||
if (neg)
|
||||
return(-huge);
|
||||
return(-HUGE_VAL);
|
||||
else
|
||||
return(huge);
|
||||
return(HUGE_VAL);
|
||||
}
|
||||
if (exp < -127)
|
||||
if (exp < DBL_MIN_EXP - 2)
|
||||
return(0);
|
||||
while (exp > 30) {
|
||||
fr = fr*(1L<<30);
|
||||
|
||||
@@ -20,7 +20,8 @@ include $(TOPSRC)/target.mk
|
||||
CFLAGS += ${DEFS}
|
||||
|
||||
OBJS = addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \
|
||||
mulsf3.o negsf2.o subsf3.o sc_case.o
|
||||
mulsf3.o negsf2.o subsf3.o sc_case.o fixunssfsi.o \
|
||||
floatunsisf.o
|
||||
|
||||
all: ${OBJS}
|
||||
|
||||
|
||||
45
src/libc/runtime/fixunssfsi.c
Normal file
45
src/libc/runtime/fixunssfsi.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/* ===-- fixunssfsi.c - Implement __fixunssfsi -----------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __fixunssfsi for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
/* Returns: convert a to a unsigned int, rounding toward zero.
|
||||
* Negative values all become zero.
|
||||
*/
|
||||
|
||||
/* Assumption: float is a IEEE 32 bit floating point type
|
||||
* su_int is a 32 bit integral type
|
||||
* value in float is representable in su_int or is negative
|
||||
* (no range checking performed)
|
||||
*/
|
||||
|
||||
/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */
|
||||
|
||||
uint32_t
|
||||
__fixunssfsi(fp_t a)
|
||||
{
|
||||
union { fp_t f; rep_t u; } fb;
|
||||
fb.f = a;
|
||||
|
||||
int e = ((fb.u & 0x7F800000) >> 23) - 127;
|
||||
if (e < 0 || (fb.u & 0x80000000))
|
||||
return 0;
|
||||
|
||||
rep_t r = (fb.u & 0x007FFFFF) | 0x00800000;
|
||||
if (e > 23)
|
||||
r <<= (e - 23);
|
||||
else
|
||||
r >>= (23 - e);
|
||||
return r;
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
//#include "int_lib.h"
|
||||
|
||||
fp_t
|
||||
__floatsisf(int a)
|
||||
{
|
||||
|
||||
47
src/libc/runtime/floatunsisf.c
Normal file
47
src/libc/runtime/floatunsisf.c
Normal file
@@ -0,0 +1,47 @@
|
||||
//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements unsigned integer to single-precision conversion for the
|
||||
// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
|
||||
// mode.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define SINGLE_PRECISION
|
||||
#include "fp_lib.h"
|
||||
|
||||
fp_t
|
||||
__floatunsisf(unsigned int a)
|
||||
{
|
||||
const int aWidth = sizeof a * CHAR_BIT;
|
||||
|
||||
// Handle zero as a special case to protect clz
|
||||
if (a == 0)
|
||||
return fromRep(0);
|
||||
|
||||
// Exponent of (fp_t)a is the width of abs(a).
|
||||
const int exponent = (aWidth - 1) - __builtin_clz(a);
|
||||
rep_t result;
|
||||
|
||||
// Shift a into the significand field, rounding if it is a right-shift
|
||||
if (exponent <= significandBits) {
|
||||
const int shift = significandBits - exponent;
|
||||
result = (rep_t)a << shift ^ implicitBit;
|
||||
} else {
|
||||
const int shift = exponent - significandBits;
|
||||
result = (rep_t)a >> shift ^ implicitBit;
|
||||
rep_t round = (rep_t)a << (typeWidth - shift);
|
||||
if (round > signBit) result++;
|
||||
if (round == signBit) result += result & 1;
|
||||
}
|
||||
|
||||
// Insert the exponent
|
||||
result += (rep_t)(exponent + exponentBias) << significandBits;
|
||||
return fromRep(result);
|
||||
}
|
||||
@@ -41,8 +41,10 @@
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Max number conversion buffer length: a long in base 2, plus NUL byte. */
|
||||
#define MAXNBUF (sizeof(long) * 8 + 1)
|
||||
/* Max number conversion buffer length. */
|
||||
#define MAXNBUF \
|
||||
(1/*sign*/ + DBL_MAX_10_EXP+1/*max integral digits*/ + \
|
||||
1/*.*/ + DBL_DIG+1/*max fractional digits*/ + 1/*NUL*/)
|
||||
|
||||
static unsigned char *ksprintn (unsigned char *buf, unsigned long v, unsigned char base,
|
||||
int width, unsigned char *lp);
|
||||
@@ -169,21 +171,11 @@ reswitch: switch (c = *fmt++) {
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
s = va_arg (ap, const unsigned char*);
|
||||
if (! width)
|
||||
width = 16;
|
||||
if (sharpflag)
|
||||
padding = ':';
|
||||
while (width--) {
|
||||
c = *s++;
|
||||
PUTC (mkhex (c >> 4));
|
||||
PUTC (mkhex (c));
|
||||
if (width)
|
||||
PUTC (padding);
|
||||
}
|
||||
break;
|
||||
lflag=1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
ul = lflag ? va_arg (ap, long) : va_arg (ap, int);
|
||||
if (! sign) sign = 1;
|
||||
base = 10;
|
||||
@@ -209,7 +201,7 @@ reswitch: switch (c = *fmt++) {
|
||||
sharpflag = (width == 0);
|
||||
goto nosign;
|
||||
|
||||
case 'n':
|
||||
case 'n': /* TBD!!! fix this non-standard %n */
|
||||
ul = lflag ? va_arg (ap, unsigned long) :
|
||||
sign ? (unsigned long) va_arg (ap, int) :
|
||||
va_arg (ap, unsigned int);
|
||||
@@ -292,7 +284,7 @@ cnt_unknown: if (ladjust)
|
||||
goto number;
|
||||
|
||||
nosign: sign = 0;
|
||||
number: if (sign && ((long) ul != 0L)) {
|
||||
number: if (sign) {
|
||||
if ((long) ul < 0L) {
|
||||
neg = '-';
|
||||
ul = -(long) ul;
|
||||
@@ -403,7 +395,7 @@ number: if (sign && ((long) ul != 0L)) {
|
||||
nbuf [size + 1] = 0;
|
||||
}
|
||||
}
|
||||
if (neg)
|
||||
if (neg || sign)
|
||||
size++;
|
||||
if (! ladjust && width && padding == ' ' &&
|
||||
(width -= size) > 0)
|
||||
@@ -411,8 +403,11 @@ number: if (sign && ((long) ul != 0L)) {
|
||||
PUTC (' ');
|
||||
} while (--width > 0);
|
||||
|
||||
if (neg)
|
||||
if (neg) {
|
||||
PUTC ('-');
|
||||
} else if (sign) {
|
||||
PUTC ('+');
|
||||
}
|
||||
|
||||
if (! ladjust && width && (width -= size) > 0)
|
||||
do {
|
||||
|
||||
@@ -5,8 +5,8 @@ CFLAGS += -O -Wall -Werror
|
||||
MAN = gpanel.0
|
||||
MANSRC = gpanel.3
|
||||
|
||||
OBJS = open.o clear.o pixel.o line.o rect.o fill.o circle.o \
|
||||
image.o char.o text.o text_width.o
|
||||
OBJS = open.o clear.o pixel.o line.o rect.o fill.o fill_triangle.o \
|
||||
circle.o image.o char.o text.o text_width.o
|
||||
|
||||
all: ../libgpanel.a $(MAN)
|
||||
|
||||
|
||||
125
src/libgpanel/fill_triangle.c
Normal file
125
src/libgpanel/fill_triangle.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Fill a triangle.
|
||||
* Code ported from AdaFruit TFT LCD library.
|
||||
*
|
||||
* Copyright (C) 2015 Serge Vakulenko, <serge@vak.ru>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software
|
||||
* and its documentation for any purpose and without fee is hereby
|
||||
* granted, provided that the above copyright notice appear in all
|
||||
* copies and that both that the copyright notice and this
|
||||
* permission notice and warranty disclaimer appear in supporting
|
||||
* documentation, and that the name of the author not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
*
|
||||
* The author disclaim all warranties with regard to this
|
||||
* software, including all implied warranties of merchantability
|
||||
* and fitness. In no event shall the author be liable for any
|
||||
* special, indirect or consequential damages or any damages
|
||||
* whatsoever resulting from loss of use, data or profits, whether
|
||||
* in an action of contract, negligence or other tortious action,
|
||||
* arising out of or in connection with the use or performance of
|
||||
* this software.
|
||||
*/
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/gpanel.h>
|
||||
|
||||
/*
|
||||
* Swap values of two integer variables.
|
||||
*/
|
||||
#define swapi(x,y) { int _t = x; x = y; y = _t; }
|
||||
|
||||
void gpanel_fill_triangle(int color, int x0, int y0,
|
||||
int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int a, b, y, last;
|
||||
|
||||
// Sort coordinates by Y order (y2 >= y1 >= y0)
|
||||
if (y0 > y1) {
|
||||
swapi(y0, y1);
|
||||
swapi(x0, x1);
|
||||
}
|
||||
if (y1 > y2) {
|
||||
swapi(y2, y1);
|
||||
swapi(x2, x1);
|
||||
}
|
||||
if (y0 > y1) {
|
||||
swapi(y0, y1);
|
||||
swapi(x0, x1);
|
||||
}
|
||||
|
||||
if (y0 == y2) {
|
||||
// Handle awkward all-on-same-line case as its own thing
|
||||
a = b = x0;
|
||||
|
||||
if (x1 < a)
|
||||
a = x1;
|
||||
else if (x1 > b)
|
||||
b = x1;
|
||||
|
||||
if (x2 < a)
|
||||
a = x2;
|
||||
else if (x2 > b)
|
||||
b = x2;
|
||||
|
||||
gpanel_fill(color, a, y0, b, y0);
|
||||
return;
|
||||
}
|
||||
|
||||
int dx01 = x1 - x0;
|
||||
int dy01 = y1 - y0;
|
||||
int dx02 = x2 - x0;
|
||||
int dy02 = y2 - y0;
|
||||
int dx12 = x2 - x1;
|
||||
int dy12 = y2 - y1;
|
||||
int sa = 0;
|
||||
int sb = 0;
|
||||
|
||||
// For upper part of triangle, find scanline crossings for segments
|
||||
// 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
|
||||
// is included here (and second loop will be skipped, avoiding a /0
|
||||
// error there), otherwise scanline y1 is skipped here and handled
|
||||
// in the second loop...which also avoids a /0 error here if y0=y1
|
||||
// (flat-topped triangle).
|
||||
if (y1 == y2)
|
||||
last = y1; // Include y1 scanline
|
||||
else
|
||||
last = y1-1; // Skip it
|
||||
|
||||
for (y=y0; y<=last; y++) {
|
||||
a = x0 + sa / dy01;
|
||||
b = x0 + sb / dy02;
|
||||
sa += dx01;
|
||||
sb += dx02;
|
||||
|
||||
/* longhand:
|
||||
* a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
|
||||
* b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
|
||||
*/
|
||||
if (a > b)
|
||||
swapi(a, b);
|
||||
|
||||
gpanel_fill(color, a, y, b, y);
|
||||
}
|
||||
|
||||
// For lower part of triangle, find scanline crossings for segments
|
||||
// 0-2 and 1-2. This loop is skipped if y1=y2.
|
||||
sa = dx12 * (y - y1);
|
||||
sb = dx02 * (y - y0);
|
||||
for (; y<=y2; y++) {
|
||||
a = x1 + sa / dy12;
|
||||
b = x0 + sb / dy02;
|
||||
sa += dx12;
|
||||
sb += dx02;
|
||||
|
||||
/* longhand:
|
||||
* a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
|
||||
* b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
|
||||
*/
|
||||
if (a > b)
|
||||
swapi(a, b);
|
||||
|
||||
gpanel_fill(color, a, y, b, y);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
*
|
||||
* The coefficients are #1069 from Hart and Cheney. (22.35D)
|
||||
*/
|
||||
#include <float.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
@@ -16,7 +17,7 @@ static double q1 = .3277251518082914423057964422e6;
|
||||
static double q2 = .1749287689093076403844945335e4;
|
||||
static double log2e = 1.4426950408889634073599247;
|
||||
static double sqrt2 = 1.4142135623730950488016887;
|
||||
static double maxf = 10000;
|
||||
static double maxf = DBL_MAX_10_EXP * 2.5/*>ln(10)*/;
|
||||
|
||||
double
|
||||
exp(arg)
|
||||
@@ -32,7 +33,7 @@ double arg;
|
||||
return(0.);
|
||||
if(arg > maxf) {
|
||||
errno = ERANGE;
|
||||
return(HUGE);
|
||||
return(HUGE_VAL);
|
||||
}
|
||||
arg *= log2e;
|
||||
ent = floor(arg);
|
||||
|
||||
207
src/libm/fmod.c
207
src/libm/fmod.c
@@ -1,27 +1,161 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ieee.h"
|
||||
typedef union {
|
||||
double value;
|
||||
struct {
|
||||
uint32_t lo;
|
||||
uint32_t hi;
|
||||
} uns;
|
||||
} union64_t;
|
||||
|
||||
/*
|
||||
* Get two 32 bit ints from a double.
|
||||
*/
|
||||
#define UNPACK_DOUBLE(high,low,d) {\
|
||||
union64_t u = {0}; \
|
||||
u.value = d; \
|
||||
high = u.uns.hi; \
|
||||
low = u.uns.lo; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a double from two 32 bit ints.
|
||||
*/
|
||||
#define PACK_DOUBLE(d,high,low) { \
|
||||
union64_t u = {0}; \
|
||||
u.uns.hi = high; \
|
||||
u.uns.lo = low; \
|
||||
d = u.value; \
|
||||
}
|
||||
|
||||
typedef union {
|
||||
float value;
|
||||
uint32_t word;
|
||||
} union32_t;
|
||||
|
||||
/*
|
||||
* Get two 32 bit ints from a double.
|
||||
*/
|
||||
#define UNPACK_FLOAT(w,f) {\
|
||||
union32_t u = {0}; \
|
||||
u.value = f; \
|
||||
w = u.word; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a double from two 32 bit ints.
|
||||
*/
|
||||
#define PACK_FLOAT(f,w) { \
|
||||
union32_t u = {0}; \
|
||||
u.word = w; \
|
||||
f = u.value; \
|
||||
}
|
||||
|
||||
static const double one = 1.0, Zero[] = {0.0, -0.0,};
|
||||
|
||||
double fmod(double x, double y)
|
||||
{
|
||||
int32_t n=0, hx=0, hy=0, hz=0, ix=0, iy=0, sx=0, i=0;
|
||||
uint32_t lx=0,ly=0,lz=0;
|
||||
|
||||
EXTRACT_WORDS(hx,lx,x);
|
||||
EXTRACT_WORDS(hy,ly,y);
|
||||
if (sizeof(float) == sizeof(double)) {
|
||||
/*
|
||||
* Double is 32-bit.
|
||||
*/
|
||||
UNPACK_FLOAT(hx,x);
|
||||
UNPACK_FLOAT(hy,y);
|
||||
sx = hx & 0x80000000; /* sign of x */
|
||||
hx ^= sx; /* |x| */
|
||||
hy &= 0x7fffffff; /* |y| */
|
||||
|
||||
/* purge off exception values */
|
||||
if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
|
||||
((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
|
||||
if (hy == 0 || hx >= 0x7f800000 || /* y=0, or x not finite */
|
||||
hy > 0x7f800000) /* or y is NaN */
|
||||
return (x*y) / (x*y);
|
||||
if (hx < hy)
|
||||
return x; /* |x| < |y| return x */
|
||||
if (hx == hy)
|
||||
return Zero[(uint32_t)sx >> 31]; /* |x| = |y| return x*0*/
|
||||
|
||||
/* determine ix = ilogb(x) */
|
||||
if (hx < 0x00800000) { /* subnormal x */
|
||||
for (ix= -126, i=hx<<8; i>0; i<<=1)
|
||||
ix -= 1;
|
||||
} else
|
||||
ix = (hx >> 23) - 127;
|
||||
|
||||
/* determine iy = ilogb(y) */
|
||||
if (hy < 0x00800000) { /* subnormal y */
|
||||
for (iy= -126, i=hy<<8; i>=0; i<<=1)
|
||||
iy -= 1;
|
||||
} else iy = (hy >> 23) - 127;
|
||||
|
||||
/* set up {hx,lx}, {hy,ly} and align y to x */
|
||||
if (ix >= -126)
|
||||
hx = 0x00800000 | (0x007fffff & hx);
|
||||
else { /* subnormal x, shift x to normal */
|
||||
n = -126 - ix;
|
||||
hx = hx << n;
|
||||
}
|
||||
if (iy >= -126)
|
||||
hy = 0x00800000 | (0x007fffff & hy);
|
||||
else { /* subnormal y, shift y to normal */
|
||||
n = -126 - iy;
|
||||
hy = hy << n;
|
||||
}
|
||||
|
||||
/* fix point fmod */
|
||||
n = ix - iy;
|
||||
while (n--) {
|
||||
hz = hx - hy;
|
||||
if (hz < 0) {
|
||||
hx = hx + hx;
|
||||
} else {
|
||||
if (hz == 0) /* return sign(x)*0 */
|
||||
return Zero[(uint32_t)sx >> 31];
|
||||
hx = hz + hz;
|
||||
}
|
||||
}
|
||||
hz = hx - hy;
|
||||
if (hz >= 0) {
|
||||
hx = hz;
|
||||
}
|
||||
|
||||
/* convert back to floating value and restore the sign */
|
||||
if (hx == 0) /* return sign(x)*0 */
|
||||
return Zero[(uint32_t)sx >> 31];
|
||||
while (hx < 0x00800000) { /* normalize x */
|
||||
hx = hx + hx;
|
||||
iy -= 1;
|
||||
}
|
||||
if (iy >= -126) { /* normalize output */
|
||||
hx = (hx - 0x00800000) | ((iy + 127) << 23);
|
||||
PACK_FLOAT(x, hx | sx);
|
||||
} else { /* subnormal output */
|
||||
n = -126 - iy;
|
||||
hx >>= n;
|
||||
PACK_FLOAT(x, hx | sx);
|
||||
x *= one; /* create necessary signal */
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Double is 64-bit.
|
||||
*/
|
||||
uint32_t lx=0, ly=0, lz=0;
|
||||
|
||||
UNPACK_DOUBLE(hx, lx, x);
|
||||
UNPACK_DOUBLE(hy, ly, y);
|
||||
sx = hx & 0x80000000; /* sign of x */
|
||||
hx ^= sx; /* |x| */
|
||||
hy &= 0x7fffffff; /* |y| */
|
||||
|
||||
/* purge off exception values */
|
||||
if ((hy | ly) == 0 || hx >= 0x7ff00000 || /* y=0,or x not finite */
|
||||
(hy | ((ly | -ly) >> 31)) > 0x7ff00000) /* or y is NaN */
|
||||
return (x*y) / (x*y);
|
||||
if (hx <= hy) {
|
||||
if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
|
||||
if (hx < hy || lx < ly)
|
||||
return x; /* |x| < |y| return x */
|
||||
if (lx == ly)
|
||||
return Zero[(uint32_t)sx >> 31]; /* |x| = |y| return x*0 */
|
||||
}
|
||||
@@ -29,20 +163,26 @@ double fmod(double x, double y)
|
||||
/* determine ix = ilogb(x) */
|
||||
if (hx < 0x00100000) { /* subnormal x */
|
||||
if (hx == 0) {
|
||||
for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
|
||||
for (ix = -1043, i=lx; i>0; i<<=1)
|
||||
ix -= 1;
|
||||
} else {
|
||||
for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
|
||||
for (ix = -1022, i=hx<<11; i>0; i<<=1)
|
||||
ix -= 1;
|
||||
}
|
||||
} else ix = (hx>>20)-1023;
|
||||
} else
|
||||
ix = (hx >> 20) - 1023;
|
||||
|
||||
/* determine iy = ilogb(y) */
|
||||
if (hy < 0x00100000) { /* subnormal y */
|
||||
if(hy==0) {
|
||||
for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
|
||||
for (iy = -1043, i=ly; i>0; i<<=1)
|
||||
iy -= 1;
|
||||
} else {
|
||||
for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
|
||||
for (iy = -1022,i=(hy<<11); i>0; i<<=1)
|
||||
iy -= 1;
|
||||
}
|
||||
} else iy = (hy>>20)-1023;
|
||||
} else
|
||||
iy = (hy >> 20) - 1023;
|
||||
|
||||
/* set up {hx,lx}, {hy,ly} and align y to x */
|
||||
if (ix >= -1022)
|
||||
@@ -73,39 +213,56 @@ double fmod(double x, double y)
|
||||
/* fix point fmod */
|
||||
n = ix - iy;
|
||||
while (n--) {
|
||||
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
|
||||
if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
|
||||
else {
|
||||
hz = hx - hy;
|
||||
lz = lx - ly;
|
||||
if (lx < ly)
|
||||
hz -= 1;
|
||||
|
||||
if (hz < 0) {
|
||||
hx = hx + hx + (lx >> 31);
|
||||
lx = lx + lx;
|
||||
} else {
|
||||
if ((hz | lz) == 0) /* return sign(x)*0 */
|
||||
return Zero[(uint32_t)sx >> 31];
|
||||
hx = hz+hz+(lz>>31); lx = lz+lz;
|
||||
hx = hz + hz + (lz >> 31);
|
||||
lx = lz + lz;
|
||||
}
|
||||
}
|
||||
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
|
||||
if(hz>=0) {hx=hz;lx=lz;}
|
||||
hz = hx - hy;
|
||||
lz = lx - ly;
|
||||
if (lx < ly)
|
||||
hz -= 1;
|
||||
if (hz >= 0) {
|
||||
hx = hz;
|
||||
lx = lz;
|
||||
}
|
||||
|
||||
/* convert back to floating value and restore the sign */
|
||||
if ((hx | lx) == 0) /* return sign(x)*0 */
|
||||
return Zero[(uint32_t)sx >> 31];
|
||||
while (hx < 0x00100000) { /* normalize x */
|
||||
hx = hx+hx+(lx>>31); lx = lx+lx;
|
||||
hx = hx + hx + (lx >> 31);
|
||||
lx = lx + lx;
|
||||
iy -= 1;
|
||||
}
|
||||
if (iy >= -1022) { /* normalize output */
|
||||
hx = ((hx-0x00100000)|((iy+1023)<<20));
|
||||
INSERT_WORDS(x,hx|sx,lx);
|
||||
hx = (hx - 0x00100000) | ((iy + 1023) << 20);
|
||||
PACK_DOUBLE(x, hx | sx, lx);
|
||||
} else { /* subnormal output */
|
||||
n = -1022 - iy;
|
||||
if (n <= 20) {
|
||||
lx = (lx >> n) | ((uint32_t)hx << (32 - n));
|
||||
hx >>= n;
|
||||
} else if (n <= 31) {
|
||||
lx = (hx<<(32-n))|(lx>>n); hx = sx;
|
||||
lx = (hx << (32 - n)) | (lx >> n);
|
||||
hx = sx;
|
||||
} else {
|
||||
lx = hx>>(n-32); hx = sx;
|
||||
lx = hx >> (n - 32);
|
||||
hx = sx;
|
||||
}
|
||||
INSERT_WORDS(x,hx|sx,lx);
|
||||
PACK_DOUBLE(x, hx | sx, lx);
|
||||
x *= one; /* create necessary signal */
|
||||
}
|
||||
}
|
||||
return x; /* exact output */
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/* Get two 32 bit ints from a double. */
|
||||
|
||||
#define EXTRACT_WORDS(high,low,d) \
|
||||
high = *(unsigned long long*) &d; \
|
||||
low = (*(unsigned long long*) &d) >> 32
|
||||
|
||||
|
||||
/* Set a double from two 32 bit ints. */
|
||||
|
||||
#define INSERT_WORDS(d,high,low) \
|
||||
*(unsigned long long*) &(x) = (unsigned long long) (high) << 32 | (low)
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
double value;
|
||||
struct
|
||||
{
|
||||
uint32_t lsw;
|
||||
uint32_t msw;
|
||||
} parts;
|
||||
} ieee_double_shape_type;
|
||||
|
||||
@@ -176,7 +176,7 @@ y0(arg)
|
||||
errno = 0;
|
||||
if(arg <= 0.){
|
||||
errno = EDOM;
|
||||
return(-HUGE);
|
||||
return(-HUGE_VAL);
|
||||
}
|
||||
if(arg > 8.){
|
||||
asympt(arg);
|
||||
|
||||
@@ -182,7 +182,7 @@ y1(arg)
|
||||
x = arg;
|
||||
if(x <= 0.){
|
||||
errno = EDOM;
|
||||
return(-HUGE);
|
||||
return(-HUGE_VAL);
|
||||
}
|
||||
if(x > 8.){
|
||||
asympt(x);
|
||||
|
||||
@@ -82,7 +82,7 @@ yn(n,x) int n; double x;{
|
||||
|
||||
if (x <= 0) {
|
||||
errno = EDOM;
|
||||
return(-HUGE);
|
||||
return(-HUGE_VAL);
|
||||
}
|
||||
sign = 1;
|
||||
if(n<0){
|
||||
|
||||
@@ -31,7 +31,7 @@ double arg;
|
||||
|
||||
if(arg <= 0.) {
|
||||
errno = EDOM;
|
||||
return(-HUGE);
|
||||
return(-HUGE_VAL);
|
||||
}
|
||||
x = frexp(arg,&exp);
|
||||
while(x<0.5) {
|
||||
|
||||
@@ -64,8 +64,8 @@ tan(arg)
|
||||
if(temp == 0.) {
|
||||
errno = ERANGE;
|
||||
if (sign>0)
|
||||
return(HUGE);
|
||||
return(-HUGE);
|
||||
return(HUGE_VAL);
|
||||
return(-HUGE_VAL);
|
||||
}
|
||||
temp = 1./temp;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif /* !MAL */
|
||||
|
||||
char *
|
||||
imalloc(n)
|
||||
imalloc(int n)
|
||||
{
|
||||
#ifdef MAL
|
||||
register char * result;
|
||||
@@ -33,7 +33,7 @@ imalloc(n)
|
||||
}
|
||||
|
||||
char *
|
||||
icalloc(nelem, elsize)
|
||||
icalloc(int nelem, int elsize)
|
||||
{
|
||||
if (nelem == 0 || elsize == 0)
|
||||
nelem = elsize = 1;
|
||||
@@ -41,8 +41,7 @@ icalloc(nelem, elsize)
|
||||
}
|
||||
|
||||
char *
|
||||
irealloc(pointer, size)
|
||||
char * pointer;
|
||||
irealloc(char *pointer, int size)
|
||||
{
|
||||
if (NULLMAL(pointer))
|
||||
return imalloc(size);
|
||||
|
||||
@@ -26,6 +26,7 @@ static void
|
||||
show(zone, t, v)
|
||||
char * zone;
|
||||
time_t t;
|
||||
int v;
|
||||
{
|
||||
struct tm * tmp;
|
||||
|
||||
|
||||
@@ -309,6 +309,8 @@ static void
|
||||
eats(name, num, rname, rnum)
|
||||
char * name;
|
||||
char * rname;
|
||||
int num;
|
||||
int rnum;
|
||||
{
|
||||
filename = name;
|
||||
linenum = num;
|
||||
@@ -319,6 +321,7 @@ char * rname;
|
||||
static void
|
||||
eat(name, num)
|
||||
char * name;
|
||||
int num;
|
||||
{
|
||||
eats(name, num, (char *) NULL, -1);
|
||||
}
|
||||
@@ -653,6 +656,7 @@ static long
|
||||
gethms(string, errstring, signable)
|
||||
char * string;
|
||||
char * errstring;
|
||||
int signable;
|
||||
{
|
||||
int hh, mm, ss, sign;
|
||||
|
||||
@@ -687,6 +691,7 @@ char * errstring;
|
||||
static void
|
||||
inrule(fields, nfields)
|
||||
register char ** fields;
|
||||
int nfields;
|
||||
{
|
||||
struct rule r;
|
||||
|
||||
@@ -713,6 +718,7 @@ register char ** fields;
|
||||
static int
|
||||
inzone(fields, nfields)
|
||||
register char ** fields;
|
||||
int nfields;
|
||||
{
|
||||
register int i;
|
||||
char buf[132];
|
||||
@@ -745,6 +751,7 @@ register char ** fields;
|
||||
static int
|
||||
inzcont(fields, nfields)
|
||||
register char ** fields;
|
||||
int nfields;
|
||||
{
|
||||
if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
|
||||
error("wrong number of fields on Zone continuation line");
|
||||
@@ -756,6 +763,8 @@ register char ** fields;
|
||||
static int
|
||||
inzsub(fields, nfields, iscont)
|
||||
register char ** fields;
|
||||
int nfields;
|
||||
int iscont;
|
||||
{
|
||||
register char * cp;
|
||||
struct zone z;
|
||||
@@ -826,6 +835,7 @@ error("Zone continuation line end time is not after end time of previous line");
|
||||
static void
|
||||
inlink(fields, nfields)
|
||||
register char ** fields;
|
||||
int nfields;
|
||||
{
|
||||
struct link l;
|
||||
|
||||
@@ -1055,6 +1065,7 @@ char * name;
|
||||
static void
|
||||
outzone(zpfirst, zonecount)
|
||||
struct zone * zpfirst;
|
||||
int zonecount;
|
||||
{
|
||||
register struct zone * zp;
|
||||
register struct rule * rp;
|
||||
@@ -1200,6 +1211,7 @@ addtt(starttime, addtype(startoff, startbuf, startisdst));
|
||||
static void
|
||||
addtt(starttime, type)
|
||||
time_t starttime;
|
||||
int type;
|
||||
{
|
||||
if (timecnt != 0 && type == types[timecnt - 1])
|
||||
return; /* easy enough! */
|
||||
@@ -1216,6 +1228,7 @@ static int
|
||||
addtype(gmtoff, abbr, isdst)
|
||||
long gmtoff;
|
||||
char * abbr;
|
||||
int isdst;
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
@@ -1251,6 +1264,7 @@ char * abbr;
|
||||
|
||||
static int
|
||||
yearistype(year, type)
|
||||
int year;
|
||||
char * type;
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
@@ -1276,7 +1290,7 @@ char * type;
|
||||
}
|
||||
|
||||
static int
|
||||
lowerit(a)
|
||||
lowerit(int a)
|
||||
{
|
||||
return (isascii(a) && isupper(a)) ? tolower(a) : a;
|
||||
}
|
||||
@@ -1538,7 +1552,7 @@ char * name;
|
||||
}
|
||||
|
||||
static long
|
||||
eitol(i)
|
||||
eitol(int i)
|
||||
{
|
||||
long l;
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ void gpanel_pixel(int color, int x, int y);
|
||||
void gpanel_line(int color, int x0, int y0, int x1, int y1);
|
||||
void gpanel_rect(int color, int x0, int y0, int x1, int y1);
|
||||
void gpanel_fill(int color, int x0, int y0, int x1, int y1);
|
||||
void gpanel_fill_triangle(int color, int x0, int y0, int x1, int y1, int x2, int y2);
|
||||
void gpanel_circle(int color, int x, int y, int radius);
|
||||
void gpanel_image(int x, int y, int width, int height, const unsigned short *data);
|
||||
void gpanel_char(const struct gpanel_font_t *font, int color, int background, int x, int y, int sym);
|
||||
@@ -124,12 +125,47 @@ extern int _gpanel_fd;
|
||||
/*
|
||||
* Kernel driver routines.
|
||||
*/
|
||||
struct uio;
|
||||
extern int gpanel_open(dev_t dev, int flag, int mode);
|
||||
extern int gpanel_close(dev_t dev, int flag, int mode);
|
||||
extern int gpanel_read(dev_t dev, struct uio *uio, int flag);
|
||||
extern int gpanel_write(dev_t dev, struct uio *uio, int flag);
|
||||
extern int gpanel_ioctl(dev_t dev, u_int cmd, caddr_t addr, int flag);
|
||||
|
||||
extern int gpanel_read_byte(void);
|
||||
extern void gpanel_write_byte(int value);
|
||||
extern void gpanel_cs_active(void);
|
||||
extern void gpanel_cs_idle(void);
|
||||
extern void gpanel_rs_command(void);
|
||||
extern void gpanel_rs_data(void);
|
||||
extern void gpanel_wr_strobe(void);
|
||||
extern void gpanel_read_dir(void);
|
||||
extern void gpanel_write_dir(void);
|
||||
extern int gpanel_send_command(int value);
|
||||
extern int gpanel_send_data(int value);
|
||||
|
||||
/*
|
||||
* Descriptor for access to the hardware-level driver.
|
||||
*/
|
||||
struct gpanel_hw {
|
||||
const char *name;
|
||||
void (*resize)(struct gpanel_hw *hw, int width, int height);
|
||||
void (*set_pixel)(int x, int y, int color);
|
||||
void (*fill_rectangle)(int x0, int y0, int x1, int y1, int color);
|
||||
void (*draw_image)(int x, int y, int width, int height,
|
||||
const unsigned short *data);
|
||||
void (*draw_glyph)(const struct gpanel_font_t *font,
|
||||
int color, int background, int x, int y, int width,
|
||||
const unsigned short *bits);
|
||||
};
|
||||
extern int gpanel_width;
|
||||
extern int gpanel_height;
|
||||
extern void st7781_init_display(struct gpanel_hw *hw);
|
||||
extern void nt35702_init_display(struct gpanel_hw *hw);
|
||||
extern void ili9341_init_display(struct gpanel_hw *hw);
|
||||
extern void ili9481_init_display(struct gpanel_hw *hw);
|
||||
extern void s6d04h0_init_display(struct gpanel_hw *hw);
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* _GPANEL_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
||||
"elf32-littlemips")
|
||||
OUTPUT_ARCH(mips)
|
||||
OUTPUT_ARCH(pic32mx)
|
||||
ENTRY(_reset_vector_)
|
||||
MEMORY
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ options "EXEC_AOUT" # Run a.out binaries
|
||||
options "EXEC_ELF" # Run ELF binaries
|
||||
options "EXEC_SCRIPT" # Run shell scripts
|
||||
options "UCB_METER" # Collect kernel statistics
|
||||
options "NPROC=10" # Number of processes, default 10
|
||||
options "NPROC=10" # Number of processes, default 25
|
||||
options "NBUF=10" # Number of i/o buffers, default 10
|
||||
options "NFILE=24" # Number of files, default 24
|
||||
options "NINODE=24" # Number of i-nodes, default 24
|
||||
@@ -130,8 +130,9 @@ device picga0 at spi1 pin RA4 # chip select signal
|
||||
options "PICGA_BUS=SPI1CON" # TODO: delete this option
|
||||
signal "PICGA_CS" pin RA4 # TODO: delete
|
||||
|
||||
# ST7781 TFT display driver
|
||||
device swtft
|
||||
# TFT display driver with 8-bit parallel interface.
|
||||
# Supported controllers: ST7781, ILI9341, NT35702
|
||||
device gpanel
|
||||
signal "LCD_RST" pin RB10
|
||||
signal "LCD_CS" pin RB0
|
||||
signal "LCD_RD" pin RB2
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
||||
"elf32-littlemips")
|
||||
OUTPUT_ARCH(mips)
|
||||
OUTPUT_ARCH(pic32mx)
|
||||
ENTRY(_reset_vector_)
|
||||
MEMORY
|
||||
{
|
||||
|
||||
@@ -317,7 +317,8 @@ const struct cdevsw cdevsw[] = {
|
||||
#if GPANEL_MAJOR != 16
|
||||
# error Wrong GPANEL_MAJOR value!
|
||||
#endif
|
||||
#if defined(HXTFT_ENABLED) || defined(SWTFT_ENABLED)
|
||||
#if defined(HXTFT_ENABLED) || defined(GPANEL_ENABLED) || \
|
||||
defined(SGPANEL_ENABLED)
|
||||
gpanel_open, gpanel_close, gpanel_read, gpanel_write,
|
||||
gpanel_ioctl, nulldev, 0, seltrue,
|
||||
nostrategy, 0, 0,
|
||||
|
||||
@@ -21,7 +21,7 @@ ldscript "maximite/bootloader.ld" # Linker script
|
||||
|
||||
# Standard system options
|
||||
options "CPU_KHZ=80000" # Oscillator frequency of CPU core
|
||||
options "BUS_KHZ=40000" # Frequency of peripheral bus
|
||||
options "BUS_KHZ=80000" # Frequency of peripheral bus
|
||||
options "BUS_DIV=1" # Bus clock divisor 1/2/4/8
|
||||
|
||||
# LEDs
|
||||
@@ -33,7 +33,7 @@ config unix root on sd0a
|
||||
swap on sd0b
|
||||
|
||||
# Console options
|
||||
options "CONS_MAJOR=UARTUSB_MAJOR" # UARTUSB device
|
||||
options "CONS_MAJOR=UARTUSB_MAJOR" # USB device
|
||||
|
||||
# Virtual UART on USB
|
||||
device uartusb
|
||||
@@ -50,13 +50,13 @@ signal "SD0_ENA" pin RG13 # SD card enable
|
||||
# General purpose I/O ports
|
||||
# Flags define a mask of available pins
|
||||
# The following pins excluded:
|
||||
# RD1, RD2, RD3, RG12, RG13 - spi3, SD card
|
||||
# RD15, RF2, RF8, RG12, RG13 - spi3, SD card
|
||||
device gpio0 flags 0xc6ff # port A
|
||||
device gpio1 flags 0xffff # port B
|
||||
device gpio2 flags 0xf01e # port C
|
||||
device gpio3 flags 0xfff1 # port D
|
||||
device gpio3 flags 0x7fff # port D
|
||||
device gpio4 flags 0x03ff # port E
|
||||
device gpio5 flags 0x313f # port F
|
||||
device gpio5 flags 0x303b # port F
|
||||
device gpio6 flags 0xc3cf # port G
|
||||
|
||||
# ADC driver
|
||||
|
||||
@@ -19,7 +19,7 @@ PARAM += -DUSB_NUM_STRING_DESCRIPTORS=3
|
||||
PARAM += -DUSB_MAX_EP_NUMBER=3
|
||||
PARAM += -DCONS_MAJOR=UARTUSB_MAJOR
|
||||
PARAM += -DBUS_DIV=1
|
||||
PARAM += -DBUS_KHZ=40000
|
||||
PARAM += -DBUS_KHZ=80000
|
||||
PARAM += -DCPU_KHZ=80000
|
||||
LDSCRIPT = "maximite/bootloader.ld"
|
||||
#
|
||||
|
||||
@@ -35,7 +35,7 @@ config unix root on sd0a
|
||||
options "CONS_MAJOR=UARTUSB_MAJOR" # USB device
|
||||
|
||||
# Virtual UART on USB
|
||||
device uartusb0
|
||||
device uartusb
|
||||
options "USB_MAX_EP_NUMBER=3"
|
||||
options "USB_NUM_STRING_DESCRIPTORS=3"
|
||||
|
||||
@@ -62,3 +62,20 @@ device adc
|
||||
|
||||
# PWM driver
|
||||
device pwm
|
||||
|
||||
# TFT display driver with 8-bit parallel interface.
|
||||
# Supported controllers: ST7781, ILI9341, NT35702
|
||||
device gpanel
|
||||
signal "LCD_RST" pin RB9 # arduino A4
|
||||
signal "LCD_CS" pin RB7 # arduino A3
|
||||
signal "LCD_RS" pin RB6 # arduino A2
|
||||
signal "LCD_WR" pin RB4 # arduino A1
|
||||
signal "LCD_RD" pin RB3 # arduino A0
|
||||
signal "LCD_D2" pin RE2 # arduino D2
|
||||
signal "LCD_D3" pin RE3 # arduino D3
|
||||
signal "LCD_D4" pin RE4 # arduino D4
|
||||
signal "LCD_D5" pin RE5 # arduino D5
|
||||
signal "LCD_D6" pin RE6 # arduino D6
|
||||
signal "LCD_D7" pin RE7 # arduino D7
|
||||
signal "LCD_D0" pin RB11 # arduino D8
|
||||
signal "LCD_D1" pin RB12 # arduino D9
|
||||
|
||||
@@ -11,6 +11,20 @@ PARAM += -DGPIO5_ENABLED
|
||||
PARAM += -DGPIO6_ENABLED
|
||||
PARAM += -DADC_ENABLED
|
||||
PARAM += -DPWM_ENABLED
|
||||
PARAM += -DGPANEL_ENABLED
|
||||
PARAM += -DLCD_D1_PORT=TRISB -DLCD_D1_PIN=12
|
||||
PARAM += -DLCD_D0_PORT=TRISB -DLCD_D0_PIN=11
|
||||
PARAM += -DLCD_D7_PORT=TRISE -DLCD_D7_PIN=7
|
||||
PARAM += -DLCD_D6_PORT=TRISE -DLCD_D6_PIN=6
|
||||
PARAM += -DLCD_D5_PORT=TRISE -DLCD_D5_PIN=5
|
||||
PARAM += -DLCD_D4_PORT=TRISE -DLCD_D4_PIN=4
|
||||
PARAM += -DLCD_D3_PORT=TRISE -DLCD_D3_PIN=3
|
||||
PARAM += -DLCD_D2_PORT=TRISE -DLCD_D2_PIN=2
|
||||
PARAM += -DLCD_RD_PORT=TRISB -DLCD_RD_PIN=3
|
||||
PARAM += -DLCD_WR_PORT=TRISB -DLCD_WR_PIN=4
|
||||
PARAM += -DLCD_RS_PORT=TRISB -DLCD_RS_PIN=6
|
||||
PARAM += -DLCD_CS_PORT=TRISB -DLCD_CS_PIN=7
|
||||
PARAM += -DLCD_RST_PORT=TRISB -DLCD_RST_PIN=9
|
||||
PARAM += -DSD0_ENA_PORT=TRISB -DSD0_ENA_PIN=13
|
||||
PARAM += -DLED_DISK_PORT=TRISB -DLED_DISK_PIN=12
|
||||
PARAM += -DLED_KERNEL_PORT=TRISB -DLED_KERNEL_PIN=15
|
||||
@@ -65,6 +79,7 @@ OBJS = exec_aout.o exec_conf.o exec_elf.o exec_script.o exec_subr.o \
|
||||
ufs_namei.o ufs_subr.o ufs_syscalls.o ufs_syscalls2.o \
|
||||
vfs_vnops.o vm_sched.o vm_swap.o vm_swp.o clock.o cons.o devsw.o \
|
||||
exception.o machdep.o mem.o signal.o swap.o sysctl.o adc.o \
|
||||
gpanel.o gpanel-ili9341.o gpanel-nt35702.o gpanel-st7781.o \
|
||||
gpio.o pwm.o sd.o spi.o spi_bus.o usb_device.o \
|
||||
usb_function_cdc.o usb_uart.o
|
||||
|
||||
@@ -91,7 +106,9 @@ CFILES = $S/kernel/exec_aout.c $S/kernel/exec_conf.c $S/kernel/exec_elf.c \
|
||||
$S/kernel/vm_swp.c $S/pic32/clock.c $S/pic32/cons.c \
|
||||
$S/pic32/devsw.c $S/pic32/exception.c $S/pic32/machdep.c \
|
||||
$S/pic32/mem.c $S/pic32/signal.c $S/pic32/swap.c \
|
||||
$S/pic32/sysctl.c $S/pic32/adc.c $S/pic32/gpio.c $S/pic32/pwm.c \
|
||||
$S/pic32/sysctl.c $S/pic32/adc.c $S/pic32/gpanel.c \
|
||||
$S/pic32/gpanel-ili9341.c $S/pic32/gpanel-nt35702.c \
|
||||
$S/pic32/gpanel-st7781.c $S/pic32/gpio.c $S/pic32/pwm.c \
|
||||
$S/pic32/sd.c $S/pic32/spi.c $S/pic32/spi_bus.c \
|
||||
$S/pic32/usb_device.c $S/pic32/usb_function_cdc.c \
|
||||
$S/pic32/usb_uart.c swapunix.c
|
||||
@@ -329,6 +346,18 @@ sysctl.o: $S/pic32/sysctl.c
|
||||
adc.o: $S/pic32/adc.c
|
||||
${COMPILE_C}
|
||||
|
||||
gpanel.o: $S/pic32/gpanel.c
|
||||
${COMPILE_C}
|
||||
|
||||
gpanel-ili9341.o: $S/pic32/gpanel-ili9341.c
|
||||
${COMPILE_C}
|
||||
|
||||
gpanel-nt35702.o: $S/pic32/gpanel-nt35702.c
|
||||
${COMPILE_C}
|
||||
|
||||
gpanel-st7781.o: $S/pic32/gpanel-st7781.c
|
||||
${COMPILE_C}
|
||||
|
||||
gpio.o: $S/pic32/gpio.c
|
||||
${COMPILE_C}
|
||||
|
||||
|
||||
@@ -70,6 +70,13 @@ pic32/sysctl.c standard
|
||||
#
|
||||
pic32/adc.c optional adc
|
||||
pic32/glcd.c optional glcd
|
||||
pic32/gpanel.c optional gpanel
|
||||
pic32/gpanel-ili9341.c optional gpanel
|
||||
pic32/gpanel-nt35702.c optional gpanel
|
||||
#pic32/gpanel-s6d04h0.c optional gpanel
|
||||
pic32/gpanel-st7781.c optional gpanel
|
||||
pic32/gpanel-spi.c optional sgpanel
|
||||
pic32/gpanel-spi-ili9341.c optional sgpanel
|
||||
pic32/gpio.c optional gpio
|
||||
pic32/hx8357.c optional hxtft
|
||||
pic32/picga.c optional picga
|
||||
@@ -81,7 +88,6 @@ pic32/sdramp.c optional dr
|
||||
pic32/sdram.S optional dr
|
||||
pic32/spirams.c optional sr
|
||||
pic32/sramc.c optional rc
|
||||
pic32/st7781.c optional swtft
|
||||
pic32/skel.c optional skel
|
||||
pic32/spi.c optional spi
|
||||
pic32/spi_bus.c optional spi
|
||||
|
||||
@@ -1,64 +1,8 @@
|
||||
# chipKIT PIC32 compiler from UECIDE
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# PIC32 compiler from UECIDE
|
||||
# Use UECIDE package from http://uecide.org/download
|
||||
ifndef MIPS_GCC_PREFIX
|
||||
ifdef UECIDE
|
||||
MIPS_GCC_PREFIX = $(UECIDE)/compilers/pic32-tools/bin/pic32-
|
||||
MIPS_GCC_FORMAT = elf32-tradlittlemips
|
||||
endif
|
||||
endif
|
||||
|
||||
# chipKIT PIC32 compiler on Linux
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# Download from https://github.com/jasonkajita/chipKIT-cxx/downloads
|
||||
# and unzip to /usr/local.
|
||||
# Need to copy pic32-tools/pic32mx/include/stdarg.h
|
||||
# to pic32-tools/lib/gcc/pic32mx/4.5.1/include.
|
||||
# MPLABX C32 compiler doesn't support some functionality
|
||||
# we need, so use chipKIT compiler by default.
|
||||
ifndef MIPS_GCC_PREFIX
|
||||
ifeq (/usr/local/pic32-tools/bin/pic32-gcc,$(wildcard /usr/local/pic32-tools/bin/pic32-gcc))
|
||||
MIPS_GCC_PREFIX = /usr/local/pic32-tools/bin/pic32-
|
||||
MIPS_GCC_FORMAT = elf32-tradlittlemips
|
||||
endif
|
||||
endif
|
||||
|
||||
# Generic MIPS toolchain
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~
|
||||
# You can build it from sources, as described on page
|
||||
# http://retrobsd.org/wiki/doku.php/doc/toolchain-mips
|
||||
ifndef MIPS_GCC_PREFIX
|
||||
ifeq (/usr/local/mips-gcc-4.8.1/bin/mips-elf-gcc,$(wildcard /usr/local/mips-gcc-4.8.1/bin/mips-elf-gcc))
|
||||
MIPS_GCC_PREFIX = /usr/local/mips-gcc-4.8.1/bin/mips-elf-
|
||||
endif
|
||||
endif
|
||||
|
||||
# Mentor Sourcery CodeBench Lite toolchain
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
ifndef MIPS_GCC_PREFIX
|
||||
# Download a Linux binary package from
|
||||
# https://sourcery.mentor.com/GNUToolchain/release2641
|
||||
ifeq (/usr/local/mips-2013.11/bin/mips-sde-elf-gcc,$(wildcard /usr/local/mips-2013.11/bin/mips-sde-elf-gcc))
|
||||
MIPS_GCC_PREFIX = /usr/local/mips-2013.11/bin/mips-sde-elf-
|
||||
MIPS_GCC_FORMAT = elf32-tradlittlemips
|
||||
endif
|
||||
endif
|
||||
ifndef MIPS_GCC_PREFIX
|
||||
# Download a Linux binary package from
|
||||
# https://sourcery.mentor.com/GNUToolchain/release2774
|
||||
ifeq (/usr/local/mips-2014.05/bin/mips-sde-elf-gcc,$(wildcard /usr/local/mips-2014.05/bin/mips-sde-elf-gcc))
|
||||
MIPS_GCC_PREFIX = /usr/local/mips-2014.05/bin/mips-sde-elf-
|
||||
MIPS_GCC_FORMAT = elf32-tradlittlemips
|
||||
endif
|
||||
endif
|
||||
|
||||
# Imagination Codescape MIPS SDK Essentials
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# Download a Linux binary package from:
|
||||
# http://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/download-codescape-mips-sdk-essentials/
|
||||
ifndef MIPS_GCC_ROOT
|
||||
ifeq (/opt/imgtec/Toolchains/mips-mti-elf/2015.01-7,$(wildcard /opt/imgtec/Toolchains/mips-mti-elf/2015.01-7))
|
||||
MIPS_GCC_ROOT = /opt/imgtec/Toolchains/mips-mti-elf/2015.01-7
|
||||
ifeq ($(HOME)/.uecide/compilers/pic32-tools/bin/pic32-gcc,$(wildcard $(HOME)/.uecide/compilers/pic32-tools/bin/pic32-gcc))
|
||||
MIPS_GCC_PREFIX = $(HOME)/.uecide/compilers/pic32-tools/bin/pic32-
|
||||
MIPS_GCC_FORMAT = elf32-tradlittlemips
|
||||
endif
|
||||
endif
|
||||
|
||||
458
sys/pic32/gpanel-ili9341.c
Normal file
458
sys/pic32/gpanel-ili9341.c
Normal file
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
* Display driver for ILI9341 LCD controller.
|
||||
*
|
||||
* Copyright (C) 2015 Serge Vakulenko <serge@vak.ru>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software
|
||||
* and its documentation for any purpose and without fee is hereby
|
||||
* granted, provided that the above copyright notice appear in all
|
||||
* copies and that both that the copyright notice and this
|
||||
* permission notice and warranty disclaimer appear in supporting
|
||||
* documentation, and that the name of the author not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
*
|
||||
* The author disclaim all warranties with regard to this
|
||||
* software, including all implied warranties of merchantability
|
||||
* and fitness. In no event shall the author be liable for any
|
||||
* special, indirect or consequential damages or any damages
|
||||
* whatsoever resulting from loss of use, data or profits, whether
|
||||
* in an action of contract, negligence or other tortious action,
|
||||
* arising out of or in connection with the use or performance of
|
||||
* this software.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/gpanel.h>
|
||||
#include <machine/ili9341.h>
|
||||
|
||||
/*
|
||||
* Write a 8-bit value to the ILI9341 Command register.
|
||||
*/
|
||||
static void write_command(int cmd)
|
||||
{
|
||||
gpanel_rs_command();
|
||||
gpanel_write_byte(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a 8-bit value to the ILI9341 Data register.
|
||||
*/
|
||||
static void write_data(int cmd)
|
||||
{
|
||||
gpanel_rs_data();
|
||||
gpanel_write_byte(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set address window.
|
||||
*/
|
||||
static void set_window(int x0, int y0, int x1, int y1)
|
||||
{
|
||||
write_command(ILI9341_Column_Address_Set);
|
||||
write_data(x0 >> 8);
|
||||
gpanel_write_byte(x0);
|
||||
gpanel_write_byte(x1 >> 8);
|
||||
gpanel_write_byte(x1);
|
||||
|
||||
write_command(ILI9341_Page_Address_Set);
|
||||
write_data(y0 >> 8);
|
||||
gpanel_write_byte(y0);
|
||||
gpanel_write_byte(y1 >> 8);
|
||||
gpanel_write_byte(y1);
|
||||
|
||||
write_command(ILI9341_Memory_Write);
|
||||
gpanel_rs_data();
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a pixel.
|
||||
*/
|
||||
void ili_set_pixel(int x, int y, int color)
|
||||
{
|
||||
if (x < 0 || x >= gpanel_width || y < 0 || y >= gpanel_height)
|
||||
return;
|
||||
gpanel_cs_active();
|
||||
set_window(x, y, x, y);
|
||||
gpanel_write_byte(color >> 8);
|
||||
gpanel_write_byte(color);
|
||||
gpanel_cs_idle();
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast block fill operation.
|
||||
* Requires set_window() has previously been called to set
|
||||
* the fill bounds.
|
||||
* 'npixels' is inclusive, MUST be >= 1.
|
||||
*/
|
||||
static void flood(int color, int npixels)
|
||||
{
|
||||
unsigned blocks, i;
|
||||
unsigned hi = color >> 8,
|
||||
lo = color;
|
||||
|
||||
/* Write first pixel normally, decrement counter by 1. */
|
||||
gpanel_write_byte(hi);
|
||||
gpanel_write_byte(lo);
|
||||
npixels--;
|
||||
|
||||
/* 64 pixels/block. */
|
||||
blocks = npixels >> 6;
|
||||
if (hi == lo) {
|
||||
/* High and low bytes are identical. Leave prior data
|
||||
* on the port(s) and just toggle the write strobe. */
|
||||
while (blocks--) {
|
||||
/* 64 pixels/block / 4 pixels/pass. */
|
||||
for (i = 16; i > 0; i--) {
|
||||
/* 2 bytes/pixel x 4 pixels. */
|
||||
gpanel_wr_strobe();
|
||||
gpanel_wr_strobe();
|
||||
gpanel_wr_strobe();
|
||||
gpanel_wr_strobe();
|
||||
gpanel_wr_strobe();
|
||||
gpanel_wr_strobe();
|
||||
gpanel_wr_strobe();
|
||||
gpanel_wr_strobe();
|
||||
}
|
||||
}
|
||||
/* Fill any remaining pixels (1 to 64). */
|
||||
for (i = npixels & 63; i > 0; i--) {
|
||||
gpanel_wr_strobe();
|
||||
gpanel_wr_strobe();
|
||||
}
|
||||
} else {
|
||||
while (blocks--) {
|
||||
/* 64 pixels/block / 4 pixels/pass. */
|
||||
for (i = 16; i > 0; i--) {
|
||||
gpanel_write_byte(hi); gpanel_write_byte(lo);
|
||||
gpanel_write_byte(hi); gpanel_write_byte(lo);
|
||||
gpanel_write_byte(hi); gpanel_write_byte(lo);
|
||||
gpanel_write_byte(hi); gpanel_write_byte(lo);
|
||||
}
|
||||
}
|
||||
for (i = npixels & 63; i > 0; i--) {
|
||||
gpanel_write_byte(hi);
|
||||
gpanel_write_byte(lo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch the screen orientation.
|
||||
*/
|
||||
static void ili9341_set_rotation(int rotation)
|
||||
{
|
||||
write_command(ILI9341_Memory_Access_Control);
|
||||
switch (rotation & 3) {
|
||||
case 0: /* Portrait */
|
||||
write_data(MADCTL_MX | MADCTL_BGR);
|
||||
gpanel_width = 240;
|
||||
gpanel_height = 320;
|
||||
break;
|
||||
case 1: /* Landscape */
|
||||
write_data(MADCTL_MV | MADCTL_BGR);
|
||||
gpanel_width = 320;
|
||||
gpanel_height = 240;
|
||||
break;
|
||||
case 2: /* Upside down portrait */
|
||||
write_data(MADCTL_MY | MADCTL_BGR);
|
||||
gpanel_width = 240;
|
||||
gpanel_height = 320;
|
||||
break;
|
||||
case 3: /* Upside down landscape */
|
||||
write_data(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
||||
gpanel_width = 320;
|
||||
gpanel_height = 240;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch the screen orientation.
|
||||
*/
|
||||
static void ili9481_set_rotation(int rotation)
|
||||
{
|
||||
write_command(ILI9341_Memory_Access_Control);
|
||||
switch (rotation & 3) {
|
||||
case 0: /* Portrait */
|
||||
write_data(MADCTL_MX | MADCTL_BGR);
|
||||
gpanel_width = 320;
|
||||
gpanel_height = 480;
|
||||
break;
|
||||
case 1: /* Landscape */
|
||||
write_data(MADCTL_MV | MADCTL_BGR);
|
||||
gpanel_width = 480;
|
||||
gpanel_height = 320;
|
||||
break;
|
||||
case 2: /* Upside down portrait */
|
||||
write_data(MADCTL_MY | MADCTL_BGR);
|
||||
gpanel_width = 320;
|
||||
gpanel_height = 480;
|
||||
break;
|
||||
case 3: /* Upside down landscape */
|
||||
write_data(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
||||
gpanel_width = 480;
|
||||
gpanel_height = 320;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ili9341_resize(struct gpanel_hw *h, int width, int height)
|
||||
{
|
||||
gpanel_cs_active();
|
||||
|
||||
/* Switch screen orientaation. */
|
||||
if (width > height)
|
||||
ili9341_set_rotation(1); /* Landscape */
|
||||
else if (width < height)
|
||||
ili9341_set_rotation(0); /* Portrait */
|
||||
|
||||
gpanel_cs_idle();
|
||||
}
|
||||
|
||||
static void ili9481_resize(struct gpanel_hw *h, int width, int height)
|
||||
{
|
||||
gpanel_cs_active();
|
||||
|
||||
/* Switch screen orientaation. */
|
||||
if (width > height)
|
||||
ili9481_set_rotation(1); /* Landscape */
|
||||
else if (width < height)
|
||||
ili9481_set_rotation(0); /* Portrait */
|
||||
|
||||
gpanel_cs_idle();
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill a rectangle with specified color.
|
||||
*/
|
||||
void ili_fill_rectangle(int x0, int y0, int x1, int y1, int color)
|
||||
{
|
||||
if (x0 < 0) x0 = 0;
|
||||
if (y0 < 0) x0 = 0;
|
||||
if (x1 < 0) x1 = 0;
|
||||
if (y1 < 0) x1 = 0;
|
||||
if (x0 >= gpanel_width) x0 = gpanel_width-1;
|
||||
if (x1 >= gpanel_width) x1 = gpanel_width-1;
|
||||
if (y0 >= gpanel_height) y0 = gpanel_height-1;
|
||||
if (y1 >= gpanel_height) y1 = gpanel_height-1;
|
||||
|
||||
if (x1 < x0) {
|
||||
int t = x0;
|
||||
x0 = x1;
|
||||
x1 = t;
|
||||
}
|
||||
if (y1 < y0) {
|
||||
int t = y0;
|
||||
y0 = y1;
|
||||
y1 = t;
|
||||
}
|
||||
gpanel_cs_active();
|
||||
set_window(x0, y0, x1, y1);
|
||||
flood(color, (x1 - x0 + 1) * (y1 - y0 + 1));
|
||||
gpanel_cs_idle();
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill a rectangle with user data.
|
||||
*/
|
||||
void ili_draw_image(int x, int y, int width, int height,
|
||||
const unsigned short *data)
|
||||
{
|
||||
unsigned cnt = width * height;
|
||||
int color;
|
||||
|
||||
gpanel_cs_active();
|
||||
set_window(x, y, x + width - 1, y + height - 1);
|
||||
while (cnt--) {
|
||||
color = *data++;
|
||||
gpanel_write_byte(color >> 8);
|
||||
gpanel_write_byte(color);
|
||||
}
|
||||
gpanel_cs_idle();
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a glyph of one symbol.
|
||||
*/
|
||||
void ili_draw_glyph(const struct gpanel_font_t *font,
|
||||
int color, int background, int x, int y, int width,
|
||||
const unsigned short *bits)
|
||||
{
|
||||
int h, w, c;
|
||||
unsigned bitmask = 0;
|
||||
|
||||
if (x + width > gpanel_width || y + font->height > gpanel_height)
|
||||
return;
|
||||
|
||||
if (background >= 0) {
|
||||
/*
|
||||
* Clear background.
|
||||
*/
|
||||
gpanel_cs_active();
|
||||
set_window(x, y, x + width - 1, y + font->height - 1);
|
||||
|
||||
/* Loop on each glyph row. */
|
||||
for (h=0; h<font->height; h++) {
|
||||
/* Loop on every pixel in the row (left to right). */
|
||||
for (w=0; w<width; w++) {
|
||||
if ((w & 15) == 0)
|
||||
bitmask = *bits++;
|
||||
else
|
||||
bitmask <<= 1;
|
||||
|
||||
c = (bitmask & 0x8000) ? color : background;
|
||||
gpanel_write_byte(c >> 8);
|
||||
gpanel_write_byte(c);
|
||||
}
|
||||
}
|
||||
gpanel_cs_idle();
|
||||
} else {
|
||||
/*
|
||||
* Transparent background.
|
||||
*/
|
||||
/* Loop on each glyph row. */
|
||||
for (h=0; h<font->height; h++) {
|
||||
/* Loop on every pixel in the row (left to right). */
|
||||
for (w=0; w<width; w++) {
|
||||
if ((w & 15) == 0)
|
||||
bitmask = *bits++;
|
||||
else
|
||||
bitmask <<= 1;
|
||||
|
||||
if (bitmask & 0x8000)
|
||||
ili_set_pixel(x + w, y + h, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the LCD controller.
|
||||
* Fill the gpanel_hw descriptor.
|
||||
*/
|
||||
void ili9341_init_display(struct gpanel_hw *h)
|
||||
{
|
||||
/* Use a few NOPs to synchronize after the hard Reset. */
|
||||
gpanel_cs_active();
|
||||
write_command(ILI9341_No_Operation);
|
||||
write_command(ILI9341_No_Operation);
|
||||
write_command(ILI9341_No_Operation);
|
||||
write_command(ILI9341_No_Operation);
|
||||
|
||||
write_command(ILI9341_Sleep_OUT);
|
||||
udelay(150000);
|
||||
|
||||
write_command(ILI9341_Display_OFF);
|
||||
|
||||
write_command(ILI9341_Power_Control_1);
|
||||
write_data(0x23);
|
||||
|
||||
write_command(ILI9341_Power_Control_2);
|
||||
write_data(0x10);
|
||||
|
||||
write_command(ILI9341_VCOM_Control_1);
|
||||
write_data(0x2B);
|
||||
write_data(0x2B);
|
||||
|
||||
write_command(ILI9341_VCOM_Control_2);
|
||||
write_data(0xC0);
|
||||
|
||||
write_command(ILI9341_Pixel_Format_Set);
|
||||
write_data(0x55);
|
||||
|
||||
write_command(ILI9341_Frame_Control_In_Normal_Mode);
|
||||
write_data(0x00);
|
||||
write_data(0x1B);
|
||||
|
||||
write_command(ILI9341_Entry_Mode_Set);
|
||||
write_data(0x07);
|
||||
|
||||
write_command(ILI9341_Display_ON);
|
||||
|
||||
ili9341_set_rotation(1); /* Landscape */
|
||||
gpanel_cs_idle();
|
||||
|
||||
/*
|
||||
* Fill the gpanel_hw descriptor.
|
||||
*/
|
||||
h->name = "Ilitek ILI9341";
|
||||
h->resize = ili9341_resize;
|
||||
h->set_pixel = ili_set_pixel;
|
||||
h->fill_rectangle = ili_fill_rectangle;
|
||||
h->draw_image = ili_draw_image;
|
||||
h->draw_glyph = ili_draw_glyph;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the LCD controller.
|
||||
* Fill the gpanel_hw descriptor.
|
||||
*/
|
||||
void ili9481_init_display(struct gpanel_hw *h)
|
||||
{
|
||||
/* Use a few NOPs to synchronize after the hard Reset. */
|
||||
gpanel_cs_active();
|
||||
write_command(ILI9341_No_Operation);
|
||||
write_command(ILI9341_No_Operation);
|
||||
write_command(ILI9341_No_Operation);
|
||||
write_command(ILI9341_No_Operation);
|
||||
|
||||
write_command(ILI9341_Sleep_OUT);
|
||||
udelay(150000);
|
||||
|
||||
write_command(ILI9341_NV_Memory_Write);
|
||||
write_data(0x07);
|
||||
write_data(0x42);
|
||||
write_data(0x18);
|
||||
|
||||
write_command(ILI9341_NV_Memory_Protection_Key);
|
||||
write_data(0x00);
|
||||
write_data(0x07);
|
||||
write_data(0x10);
|
||||
|
||||
write_command(ILI9341_NV_Memory_Status_Read);
|
||||
write_data(0x01);
|
||||
write_data(0x02);
|
||||
|
||||
write_command(ILI9341_Power_Control_1);
|
||||
write_data(0x10);
|
||||
write_data(0x3B);
|
||||
write_data(0x00);
|
||||
write_data(0x02);
|
||||
write_data(0x11);
|
||||
|
||||
write_command(ILI9341_VCOM_Control_1);
|
||||
write_data(0x03);
|
||||
|
||||
write_command(ILI9341_Memory_Access_Control);
|
||||
write_data(0x0A);
|
||||
|
||||
write_command(ILI9341_Pixel_Format_Set);
|
||||
write_data(0x55);
|
||||
|
||||
write_command(ILI9341_Column_Address_Set);
|
||||
write_data(0x00);
|
||||
write_data(0x00);
|
||||
write_data(0x01);
|
||||
write_data(0x3F);
|
||||
|
||||
write_command(ILI9341_Page_Address_Set);
|
||||
write_data(0x00);
|
||||
write_data(0x00);
|
||||
write_data(0x01);
|
||||
write_data(0xE0);
|
||||
|
||||
write_command(ILI9341_Display_ON);
|
||||
|
||||
ili9481_set_rotation(1); /* Landscape */
|
||||
gpanel_cs_idle();
|
||||
|
||||
/*
|
||||
* Fill the gpanel_hw descriptor.
|
||||
*/
|
||||
h->name = "Ilitek ILI9341";
|
||||
h->resize = ili9481_resize;
|
||||
h->set_pixel = ili_set_pixel;
|
||||
h->fill_rectangle = ili_fill_rectangle;
|
||||
h->draw_image = ili_draw_image;
|
||||
h->draw_glyph = ili_draw_glyph;
|
||||
}
|
||||
298
sys/pic32/gpanel-nt35702.c
Normal file
298
sys/pic32/gpanel-nt35702.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Display driver for NT35702 LCD controller.
|
||||
* This controller is partially compatible with ILI9341 chip,
|
||||
* so we can reuse most of ili_xxx() routines.
|
||||
*
|
||||
* Copyright (C) 2015 Serge Vakulenko <serge@vak.ru>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software
|
||||
* and its documentation for any purpose and without fee is hereby
|
||||
* granted, provided that the above copyright notice appear in all
|
||||
* copies and that both that the copyright notice and this
|
||||
* permission notice and warranty disclaimer appear in supporting
|
||||
* documentation, and that the name of the author not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
*
|
||||
* The author disclaim all warranties with regard to this
|
||||
* software, including all implied warranties of merchantability
|
||||
* and fitness. In no event shall the author be liable for any
|
||||
* special, indirect or consequential damages or any damages
|
||||
* whatsoever resulting from loss of use, data or profits, whether
|
||||
* in an action of contract, negligence or other tortious action,
|
||||
* arising out of or in connection with the use or performance of
|
||||
* this software.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/gpanel.h>
|
||||
|
||||
/*
|
||||
* NT35702 registers.
|
||||
*/
|
||||
#define NT35702_NOP 0x00 /* No Operation */
|
||||
#define NT35702_SWRESET 0x01 /* Software reset */
|
||||
#define NT35702_RDDID 0x04 /* Read Display ID */
|
||||
#define NT35702_RDDST 0x09 /* Read Display Status */
|
||||
#define NT35702_RDDPM 0x0A /* Read Display Power Mode */
|
||||
#define NT35702_RDDMADCTR 0x0B /* Read Display MADCTR */
|
||||
#define NT35702_RDDCOLMOD 0x0C /* Read Display Pixel Format */
|
||||
#define NT35702_RDDIM 0x0D /* Read Display Image Mode */
|
||||
#define NT35702_RDDSM 0x0E /* Read Display Signal Mode */
|
||||
#define NT35702_RDDSDR 0x0F /* Read Display Self-diagnostic result */
|
||||
#define NT35702_SLPIN 0x10 /* Sleep in & booster off */
|
||||
#define NT35702_SLPOUT 0x11 /* Sleep out & booster on */
|
||||
#define NT35702_PTLON 0x12 /* Partial mode on */
|
||||
#define NT35702_NORON 0x13 /* Partial off (Normal) */
|
||||
#define NT35702_DSBCTL 0x15 /* Deep Standby mode control */
|
||||
#define NT35702_INVOFF 0x20 /* Inversion off (normal) */
|
||||
#define NT35702_INVON 0x21 /* Inversion on */
|
||||
#define NT35702_DISPOFF 0x28 /* Display off */
|
||||
#define NT35702_DISPON 0x29 /* Display on */
|
||||
#define NT35702_CASET 0x2A /* Column address set */
|
||||
#define NT35702_RASET 0x2B /* Row address set */
|
||||
#define NT35702_RAMWR 0x2C /* Memory write */
|
||||
#define NT35702_PTLAR 0x30 /* Partial start/end address set */
|
||||
#define NT35702_SCRLAR 0x33 /* Scroll area set */
|
||||
#define NT35702_TEOFF 0x34 /* Tearing effect line off */
|
||||
#define NT35702_TEON 0x35 /* Tearing effect mode set & on */
|
||||
#define NT35702_MADCTL 0x36 /* Memory data access control */
|
||||
#define NT35702_VSCSAD 0x37 /* Scroll start address of RAM */
|
||||
#define NT35702_IDMOFF 0x38 /* Idle mode off */
|
||||
#define NT35702_IDMON 0x39 /* Idle mode on */
|
||||
#define NT35702_COLMOD 0x3A /* Interface pixel format */
|
||||
#define NT35702_WRDISBV 0x51 /* Write Display Brightness */
|
||||
#define NT35702_WRCTRLD 0x53 /* Write CTRL Display */
|
||||
#define NT35702_WRCABC 0x55 /* Write Content Adaptive Brightness Control */
|
||||
#define NT35702_WRCABCMB 0x5E /* Write CABC minimum brightness */
|
||||
#define NT35702_RDPWM 0x6A /* Read CABC Brightness */
|
||||
#define NT35702_WRPWMF 0x6B /* Write the PWM Frequency for CABC */
|
||||
#define NT35702_CABC_FOR_CE 0x77 /* Force CABC PWM in Some Conditions */
|
||||
#define NT35702_CABCDMT 0x79 /* Set Dimming Time Length for CABC */
|
||||
#define NT35702_RDID1 0xDA /* Read IDB */
|
||||
#define NT35702_RDID2 0xDB /* Read ID2 */
|
||||
#define NT35702_RDID3 0xDC /* Read ID3 */
|
||||
|
||||
#define NT35702_INVCTR 0xB4 /* Display inversion control */
|
||||
#define NT35702_DISSET5 0xB6 /* Display function setting */
|
||||
#define NT35702_SDOCTR 0xB7 /* SD output direction control */
|
||||
#define NT35702_GDOCTR 0xB8 /* GD output direction control */
|
||||
#define NT35702_PWCTR1 0xC0 /* Power control setting
|
||||
* VRH: Set the GVDD */
|
||||
#define NT35702_PWCTR2 0xC1 /* Power control setting */
|
||||
#define NT35702_PWCTR3 0xC2 /* In normal mode (Full colors)
|
||||
* AP: adjust the operational amplifier
|
||||
* DC: adjust the booster circuit for normal mode */
|
||||
#define NT35702_PWCTR4 0xC3 /* In Idle mode (8-colors)
|
||||
* AP: adjust the operational amplifier
|
||||
* DC: adjust the booster circuit for Idle mode */
|
||||
#define NT35702_PWCTR5 0xC4 /* In partial mode + Full colors
|
||||
* AP: adjust the operational amplifier
|
||||
* DC: adjust the booster circuit for Idle mode */
|
||||
#define NT35702_VMCTR1 0xC5 /* VMH: VCOMH voltage control
|
||||
* VML: VCOML voltage control */
|
||||
#define NT35702_VMOFCTR 0xC7 /* VMF: VCOM offset control */
|
||||
#define NT35702_RVMOFCTR 0xC8 /* Read the VMOF value form NV memory */
|
||||
#define NT35702_WRID2 0xD1 /* LCM version code
|
||||
* Write ID2 value to NV memory */
|
||||
#define NT35702_WRID3 0xD2 /* Customer Project code
|
||||
* Write ID3 value to NV memory */
|
||||
#define NT35702_RDID4 0xD3 /* ID41: IC vendor code
|
||||
* ID42: IC part number code
|
||||
* ID43 & ID44: chip version code */
|
||||
#define NT35702_MTP 0xD4 /* MTP access program enable */
|
||||
#define NT35702_EPWRITE 0xD5 /* NV write command */
|
||||
#define NT35702_MTPSUP 0xD7 /* MTP speed up */
|
||||
#define NT35702_GAMCTRP1 0xE0 /* Gamma adjustment (+ polarity) */
|
||||
#define NT35702_GAMCTRN1 0xE1 /* Gamma adjustment (- polarity) */
|
||||
#define NT35702_FRMCTR 0xFA /* Frame rate control */
|
||||
#define NT35702_AVDDCLP 0xFD /* AVDD Clamp Voltage */
|
||||
|
||||
/*
|
||||
* Memory Access Control register
|
||||
*/
|
||||
#define MADCTL_MY 0x80 /* Row address order */
|
||||
#define MADCTL_MX 0x40 /* Column address order */
|
||||
#define MADCTL_MV 0x20 /* Row/column exchange */
|
||||
#define MADCTL_ML 0x10 /* Vertical refresh order */
|
||||
#define MADCTL_BGR 0x08 /* Color filter selector: 0=RGB, 1=BGR */
|
||||
#define MADCTL_MH 0x04 /* Horisontal refresh direction: 1=left-to-right */
|
||||
|
||||
/*
|
||||
* Reuse ILI9341 routines.
|
||||
*/
|
||||
extern void ili_set_pixel(int x, int y, int color);
|
||||
extern void ili_fill_rectangle(int x0, int y0, int x1, int y1, int color);
|
||||
extern void ili_draw_image(int x, int y, int width, int height,
|
||||
const unsigned short *data);
|
||||
extern void ili_draw_glyph(const struct gpanel_font_t *font,
|
||||
int color, int background, int x, int y, int width,
|
||||
const unsigned short *bits);
|
||||
|
||||
/*
|
||||
* Write a 8-bit value to the NT35702 Command register.
|
||||
*/
|
||||
static void write_command(int cmd)
|
||||
{
|
||||
gpanel_rs_command();
|
||||
gpanel_write_byte(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a 8-bit value to the NT35702 Data register.
|
||||
*/
|
||||
static void write_data(int cmd)
|
||||
{
|
||||
gpanel_rs_data();
|
||||
gpanel_write_byte(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch the screen orientation.
|
||||
*/
|
||||
static void set_rotation(int rotation)
|
||||
{
|
||||
write_command(NT35702_MADCTL);
|
||||
switch (rotation & 3) {
|
||||
case 0: /* Portrait */
|
||||
write_data(MADCTL_MX | MADCTL_MY | MADCTL_BGR);
|
||||
gpanel_width = 240;
|
||||
gpanel_height = 320;
|
||||
break;
|
||||
case 1: /* Landscape */
|
||||
write_data(MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
||||
gpanel_width = 320;
|
||||
gpanel_height = 240;
|
||||
break;
|
||||
case 2: /* Upside down portrait */
|
||||
write_data(MADCTL_BGR);
|
||||
gpanel_width = 240;
|
||||
gpanel_height = 320;
|
||||
break;
|
||||
case 3: /* Upside down landscape */
|
||||
write_data(MADCTL_MX | MADCTL_MV | MADCTL_BGR);
|
||||
gpanel_width = 320;
|
||||
gpanel_height = 240;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void nt35702_resize(struct gpanel_hw *h, int width, int height)
|
||||
{
|
||||
gpanel_cs_active();
|
||||
|
||||
/* Switch screen orientaation. */
|
||||
if (width > height)
|
||||
set_rotation(1); /* Landscape */
|
||||
else if (width < height)
|
||||
set_rotation(0); /* Portrait */
|
||||
|
||||
gpanel_cs_idle();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the LCD controller.
|
||||
* Fill the gpanel_hw descriptor.
|
||||
*/
|
||||
void nt35702_init_display(struct gpanel_hw *h)
|
||||
{
|
||||
gpanel_cs_active();
|
||||
write_command(NT35702_SWRESET);
|
||||
udelay(20000);
|
||||
|
||||
write_command(NT35702_SLPOUT);
|
||||
udelay(120000);
|
||||
|
||||
write_command(NT35702_PWCTR3);
|
||||
write_data(0x05); // APA2 APA1 APA0 Large
|
||||
write_data(0x00); // Step-up cycle in Booster circuit 1
|
||||
// Step-up cycle in Booster circuit 2,3
|
||||
write_command(NT35702_PWCTR4);
|
||||
write_data(0x05); // APA2 APA1 APA0 Large
|
||||
write_data(0x00); // Step-up cycle in Booster circuit 1
|
||||
// Step-up cycle in Booster circuit 2,3
|
||||
write_command(NT35702_PWCTR5);
|
||||
write_data(0x05); // APA2 APA1 APA0 Large
|
||||
write_data(0x00); // Step-up cycle in Booster circuit 1
|
||||
// Step-up cycle in Booster circuit 2,3
|
||||
write_command(NT35702_COLMOD);
|
||||
write_data(0x55);
|
||||
|
||||
write_command(NT35702_MTPSUP);
|
||||
write_data(0x40);
|
||||
write_data(0xE0);
|
||||
|
||||
write_command(NT35702_AVDDCLP);
|
||||
write_data(0x06);
|
||||
write_data(0x11);
|
||||
|
||||
write_command(NT35702_FRMCTR);
|
||||
write_data(0x38);
|
||||
write_data(0x20);
|
||||
write_data(0x1C);
|
||||
write_data(0x10);
|
||||
write_data(0x37);
|
||||
write_data(0x12);
|
||||
write_data(0x22);
|
||||
write_data(0x1E);
|
||||
|
||||
write_command(NT35702_PWCTR1); // Set GVDD
|
||||
write_data(0x05);
|
||||
|
||||
write_command(NT35702_VMCTR1); // Set Vcom
|
||||
write_data(0x60);
|
||||
write_data(0x00);
|
||||
|
||||
write_command(NT35702_VMOFCTR); // Set VCOM-OFFSET
|
||||
write_data(0xA9); // You can fine-tune to improve flicker
|
||||
|
||||
set_rotation(1); /* Landscape */
|
||||
|
||||
write_command(NT35702_GAMCTRP1);
|
||||
write_data(0x22);
|
||||
write_data(0x23);
|
||||
write_data(0x25);
|
||||
write_data(0x08);
|
||||
write_data(0x10);
|
||||
write_data(0x14);
|
||||
write_data(0x40);
|
||||
write_data(0x7B);
|
||||
write_data(0x50);
|
||||
write_data(0x0B);
|
||||
write_data(0x1B);
|
||||
write_data(0x22);
|
||||
write_data(0x20);
|
||||
write_data(0x2F);
|
||||
write_data(0x37);
|
||||
|
||||
write_command(NT35702_GAMCTRN1);
|
||||
write_data(0x0C);
|
||||
write_data(0x14);
|
||||
write_data(0x23);
|
||||
write_data(0x0E);
|
||||
write_data(0x14);
|
||||
write_data(0x15);
|
||||
write_data(0x36);
|
||||
write_data(0x59);
|
||||
write_data(0x46);
|
||||
write_data(0x0B);
|
||||
write_data(0x1F);
|
||||
write_data(0x27);
|
||||
write_data(0x1F);
|
||||
write_data(0x20);
|
||||
write_data(0x22);
|
||||
|
||||
write_command(NT35702_DISPON);
|
||||
|
||||
write_command(NT35702_RAMWR);
|
||||
gpanel_cs_idle();
|
||||
|
||||
/*
|
||||
* Fill the gpanel_hw descriptor.
|
||||
*/
|
||||
h->name = "Novatek NT35702";
|
||||
h->resize = nt35702_resize;
|
||||
h->set_pixel = ili_set_pixel;
|
||||
h->fill_rectangle = ili_fill_rectangle;
|
||||
h->draw_image = ili_draw_image;
|
||||
h->draw_glyph = ili_draw_glyph;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user