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.
|
* specifies the terms and conditions for redistribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
double fabs(), floor(), ceil(), fmod(), ldexp();
|
double fabs(double), floor(double), ceil(double);
|
||||||
double sqrt(), hypot(), atof();
|
double sqrt(double), hypot(double, double);
|
||||||
double sin(), cos(), tan(), asin(), acos(), atan(), atan2();
|
double sin(double), cos(double), tan(double);
|
||||||
double exp(), log(), log10(), pow();
|
double asin(double), acos(double), atan(double), atan2(double, double);
|
||||||
double sinh(), cosh(), tanh();
|
double exp(double), log(double), log10(double), pow(double, double);
|
||||||
double gamma();
|
double sinh(double), cosh(double), tanh(double);
|
||||||
double j0(), j1(), jn(), y0(), y1(), yn();
|
double j0(double), j1(double), jn(int, double);
|
||||||
|
double y0(double), y1(double), yn(int, double);
|
||||||
|
|
||||||
#define HUGE 1.701411733192644270e38
|
#define HUGE_VAL 3.40282347e+38 /* TBD??? use infinity? */
|
||||||
#define LOGHUGE 39
|
|
||||||
|
|
||||||
int isnanf(float x);
|
int isnanf(float x);
|
||||||
int isnan(double x);
|
int isnan(double x);
|
||||||
|
|||||||
@@ -96,12 +96,10 @@ long random (void);
|
|||||||
char *setstate (char *);
|
char *setstate (char *);
|
||||||
void srandom (unsigned);
|
void srandom (unsigned);
|
||||||
|
|
||||||
#ifndef __SMALLER_C__
|
|
||||||
double atof (const char *);
|
double atof (const char *);
|
||||||
double strtod (const char *, char **);
|
double strtod (const char *, char **);
|
||||||
char *ecvt (double, int, int *, int *);
|
char *ecvt (double, int, int *, int *);
|
||||||
char *fcvt (double, int, int *, int *);
|
char *fcvt (double, int, int *, int *);
|
||||||
char *gcvt (double, int, char *);
|
char *gcvt (double, int, char *);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _STDLIB_H_ */
|
#endif /* _STDLIB_H_ */
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ TOPSRC = $(shell cd ..; pwd)
|
|||||||
SUBDIR = startup libc libm libcurses libtermlib libwiznet libreadline libgpanel
|
SUBDIR = startup libc libm libcurses libtermlib libwiznet libreadline libgpanel
|
||||||
PROG = ar as aout ld nm ranlib size strip
|
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)/include \
|
||||||
-idirafter $(TOPSRC)/src/cmd/ar \
|
-idirafter $(TOPSRC)/src/cmd/ar \
|
||||||
-idirafter $(TOPSRC)/src/cmd/as
|
-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)/stdlib $(LIBCDIR)/string $(LIBCDIR)/inet \
|
||||||
$(LIBCDIR)/compat $(LIBCDIR)/runtime
|
$(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
|
ASFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -I$(LIBCDIR)/mips/sys
|
||||||
|
|
||||||
# modules which can not use SYSCALL and must be assembled from sources. The
|
# 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
|
# libc/runtime
|
||||||
OBJS += addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \
|
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
|
all: ../libc.a
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
|||||||
|
|
||||||
vpath %.c $(TOPSRC)/src/libcurses
|
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 \
|
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 \
|
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
|
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 \
|
OBJS = open.o clear.o pixel.o line.o rect.o fill.o fill_triangle.o \
|
||||||
image.o char.o text.o text_width.o
|
circle.o image.o char.o text.o text_width.o
|
||||||
|
|
||||||
all: ../libgpanel.a
|
all: ../libgpanel.a
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
|||||||
|
|
||||||
vpath %.c $(TOPSRC)/src/libm
|
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 \
|
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
|
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
|
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
|
OBJS = readline.o
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
|||||||
|
|
||||||
vpath %.c $(TOPSRC)/src/libtermlib
|
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
|
OBJS = termcap.o tgoto.o tputs.o tcattr.o
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
|||||||
|
|
||||||
vpath %.c $(TOPSRC)/src/libwiznet
|
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
|
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
|
include $(TOPSRC)/target.mk
|
||||||
vpath %.c $(TOPSRC)/src/startup-mips
|
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
|
OBJS = ../crt0.o
|
||||||
|
|
||||||
|
|||||||
@@ -605,6 +605,7 @@ file /bin/whoami
|
|||||||
file /bin/write
|
file /bin/write
|
||||||
mode 02755
|
mode 02755
|
||||||
file /bin/xargs
|
file /bin/xargs
|
||||||
|
file /bin/yacc
|
||||||
file /bin/zcat
|
file /bin/zcat
|
||||||
|
|
||||||
link /bin/[
|
link /bin/[
|
||||||
@@ -671,6 +672,7 @@ default
|
|||||||
filemode 0775
|
filemode 0775
|
||||||
dir /games
|
dir /games
|
||||||
file /games/adventure
|
file /games/adventure
|
||||||
|
file /games/aclock
|
||||||
file /games/arithmetic
|
file /games/arithmetic
|
||||||
file /games/atc
|
file /games/atc
|
||||||
file /games/backgammon
|
file /games/backgammon
|
||||||
@@ -1116,6 +1118,7 @@ file /share/examples/gpanel/Makefile
|
|||||||
file /share/examples/gpanel/circle.c
|
file /share/examples/gpanel/circle.c
|
||||||
file /share/examples/gpanel/color.c
|
file /share/examples/gpanel/color.c
|
||||||
file /share/examples/gpanel/fill.c
|
file /share/examples/gpanel/fill.c
|
||||||
|
file /share/examples/gpanel/flappy.c
|
||||||
file /share/examples/gpanel/font.c
|
file /share/examples/gpanel/font.c
|
||||||
file /share/examples/gpanel/line.c
|
file /share/examples/gpanel/line.c
|
||||||
file /share/examples/gpanel/pixel.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/digits32.c
|
||||||
file /share/examples/gpanel/fonts/lucidasans11.c
|
file /share/examples/gpanel/fonts/lucidasans11.c
|
||||||
file /share/examples/gpanel/fonts/lucidasans15.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/lucidasans7.c
|
||||||
file /share/examples/gpanel/fonts/lucidasans9.c
|
file /share/examples/gpanel/fonts/lucidasans9.c
|
||||||
file /share/examples/gpanel/fonts/verdana7.c
|
file /share/examples/gpanel/fonts/verdana7.c
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
CC = cc
|
CC = cc
|
||||||
LIBS = -lgpanel
|
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 \
|
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)
|
all: $(PROG)
|
||||||
|
|
||||||
@@ -37,6 +37,9 @@ color: color.c
|
|||||||
speed: speed.c lucidasans15.o
|
speed: speed.c lucidasans15.o
|
||||||
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) speed.c lucidasans15.o $(LIBS)
|
$(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)
|
font: font.c $(FONTS)
|
||||||
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) font.c $(FONTS) $(LIBS)
|
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) font.c $(FONTS) $(LIBS)
|
||||||
|
|
||||||
@@ -58,6 +61,9 @@ lucidasans11.o: fonts/lucidasans11.c
|
|||||||
lucidasans15.o: fonts/lucidasans15.c
|
lucidasans15.o: fonts/lucidasans15.c
|
||||||
$(CC) $(CFLAGS) -o $@ -c $?
|
$(CC) $(CFLAGS) -o $@ -c $?
|
||||||
|
|
||||||
|
lucidasans28.o: fonts/lucidasans28.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ -c $?
|
||||||
|
|
||||||
lucidasans7.o: fonts/lucidasans7.c
|
lucidasans7.o: fonts/lucidasans7.c
|
||||||
$(CC) $(CFLAGS) -o $@ -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
|
CFLAGS = -Wall -O -g
|
||||||
LDFLAGS = -lpng
|
LDFLAGS = -L/opt/local/lib -lpng
|
||||||
|
|
||||||
FONTS = digits32.c \
|
FONTS = digits32.c \
|
||||||
digits20.c \
|
digits20.c \
|
||||||
@@ -47,6 +47,11 @@ lucidasans15.c: convbdf ttf/Lucida_Sans_Unicode.ttf
|
|||||||
./convbdf -u164 -a5 -d5 lucidasans15.bdf
|
./convbdf -u164 -a5 -d5 lucidasans15.bdf
|
||||||
rm -f 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
|
lucidasans9.c: convbdf ttf/Lucida_Sans_Unicode.ttf
|
||||||
-otf2bdf -p 9 -l "$(CHARSET)" ttf/Lucida_Sans_Unicode.ttf > lucidasans9.bdf
|
-otf2bdf -p 9 -l "$(CHARSET)" ttf/Lucida_Sans_Unicode.ttf > lucidasans9.bdf
|
||||||
./convbdf -u164 -a2 -d3 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 \
|
man md5 med more nm passwd pdc picoc portio printf pwm \
|
||||||
ranlib re renice retroforth scm sed setty sh sl smallc \
|
ranlib re renice retroforth scm sed setty sh sl smallc \
|
||||||
smlrc smux stty sysctl test uname wiznet xargs \
|
smlrc smux stty sysctl test uname wiznet xargs \
|
||||||
zmodem gtest msec unixbench cron compress date2 tip \
|
zmodem gtest msec cron compress date2 tip \
|
||||||
talloc uucp
|
talloc uucp yacc
|
||||||
|
|
||||||
# /sbin
|
# /sbin
|
||||||
SUBDIR += chown chroot disktool fsck getty init \
|
SUBDIR += chown chroot disktool fsck getty init \
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ exform(fcount, ifp, itype, ptype)
|
|||||||
struct {
|
struct {
|
||||||
long sa;
|
long sa;
|
||||||
int sb, sc;
|
int sb, sc;
|
||||||
|
double sd; /* assume double = float = 32 bits */
|
||||||
} fw;
|
} fw;
|
||||||
|
|
||||||
while (fcount > 0) {
|
while (fcount > 0) {
|
||||||
@@ -225,18 +226,20 @@ exform(fcount, ifp, itype, ptype)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
*(double *)&fw = 0.0;
|
case 'F':
|
||||||
|
fw.sd = 0.0;
|
||||||
fw.sa = wx;
|
fw.sa = wx;
|
||||||
print("%-16.9f", *(double *)&fw);
|
print("%-16.9f", fw.sd);
|
||||||
dotinc = 4;
|
dotinc = 4;
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
|
/* 64-bit double not supported */
|
||||||
case 'F':
|
case 'F':
|
||||||
fw.sa = wx;
|
fw.sa = wx;
|
||||||
print("%-32.18F", *(double *)&fw);
|
print("%-32.18F", *(double *)&fw);
|
||||||
dotinc = 8;
|
dotinc = 8;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case 'n': case 'N':
|
case 'n': case 'N':
|
||||||
printc('\n');
|
printc('\n');
|
||||||
dotinc = 0;
|
dotinc = 0;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
# include <time.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# include <getopt.h>
|
# include <getopt.h>
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ typedef struct {
|
|||||||
/* Header structure internal format. */
|
/* Header structure internal format. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
off_t size; /* size of the object in bytes */
|
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 lname; /* size of the long name in bytes */
|
||||||
int gid; /* group */
|
int gid; /* group */
|
||||||
int uid; /* owner */
|
int uid; /* owner */
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ delete(argv)
|
|||||||
SETCF(tfd, tname, afd, archive, NOPAD);
|
SETCF(tfd, tname, afd, archive, NOPAD);
|
||||||
copy_ar(&cf, size);
|
copy_ar(&cf, size);
|
||||||
(void)close(tfd);
|
(void)close(tfd);
|
||||||
(void)ftruncate(afd, size + SARMAG);
|
if (ftruncate(afd, size + SARMAG) < 0)
|
||||||
|
/* ignore */;
|
||||||
close_archive(afd);
|
close_archive(afd);
|
||||||
|
|
||||||
if (*argv) {
|
if (*argv) {
|
||||||
|
|||||||
@@ -136,7 +136,8 @@ move(argv)
|
|||||||
cf.rfd = tfd3;
|
cf.rfd = tfd3;
|
||||||
copy_ar(&cf, size);
|
copy_ar(&cf, size);
|
||||||
|
|
||||||
(void)ftruncate(afd, tsize + SARMAG);
|
if (ftruncate(afd, tsize + SARMAG) < 0)
|
||||||
|
/* ignore */;
|
||||||
close_archive(afd);
|
close_archive(afd);
|
||||||
|
|
||||||
if (*argv) {
|
if (*argv) {
|
||||||
|
|||||||
@@ -190,7 +190,8 @@ append: while ((file = *argv++) != 0) {
|
|||||||
cf.rfd = tfd2;
|
cf.rfd = tfd2;
|
||||||
copy_ar(&cf, size);
|
copy_ar(&cf, size);
|
||||||
|
|
||||||
(void)ftruncate(afd, tsize + SARMAG);
|
if (ftruncate(afd, tsize + SARMAG) < 0)
|
||||||
|
/* ignore */;
|
||||||
close_archive(afd);
|
close_archive(afd);
|
||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
* only. IE: A is equivalent to A0 ... Z$ is equivalent to Z0$
|
* only. IE: A is equivalent to A0 ... Z$ is equivalent to Z0$
|
||||||
*
|
*
|
||||||
* Statements:
|
* Statements:
|
||||||
* BEEP freq,ms - Generate a BEEP on the PC speaker
|
|
||||||
* CLEAR - Erase variables only
|
* CLEAR - Erase variables only
|
||||||
* CLOSE#n - Close file (0-9) opened with OPEN
|
* CLOSE#n - Close file (0-9) opened with OPEN
|
||||||
* DATA - Enter "inline" data statements
|
* DATA - Enter "inline" data statements
|
||||||
@@ -155,7 +154,7 @@
|
|||||||
#define SAVE 25
|
#define SAVE 25
|
||||||
#define LOAD 26
|
#define LOAD 26
|
||||||
#define DELAY 27
|
#define DELAY 27
|
||||||
#define BEEP 28
|
//#define BEEP 28
|
||||||
#define DOS 29
|
#define DOS 29
|
||||||
#define OUT 30
|
#define OUT 30
|
||||||
|
|
||||||
@@ -279,11 +278,6 @@ int eval_sub(void);
|
|||||||
|
|
||||||
WINDOW *win;
|
WINDOW *win;
|
||||||
|
|
||||||
void beep (int i, int t)
|
|
||||||
{
|
|
||||||
printf("BEEP not implemented yet, at line %u\n", line);
|
|
||||||
}
|
|
||||||
|
|
||||||
void delay (int msec)
|
void delay (int msec)
|
||||||
{
|
{
|
||||||
usleep (msec * 1000);
|
usleep (msec * 1000);
|
||||||
@@ -1371,11 +1365,6 @@ input: if (ii == -1)
|
|||||||
case SRND:
|
case SRND:
|
||||||
srandom(eval_num());
|
srandom(eval_num());
|
||||||
break;
|
break;
|
||||||
case BEEP:
|
|
||||||
i = eval_num();
|
|
||||||
expect(',');
|
|
||||||
beep(i, eval_num());
|
|
||||||
break;
|
|
||||||
case DOS:
|
case DOS:
|
||||||
eval_char();
|
eval_char();
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|||||||
@@ -1,13 +1,26 @@
|
|||||||
ChangeLog
|
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
|
August 10, 2015 : emg 1.8
|
||||||
-------------------------
|
-------------------------
|
||||||
Remove most buffer functions.
|
Remove most buffer functions.
|
||||||
Remove all window functions.
|
Remove all window functions.
|
||||||
Remove window.c, the one remaining function goes to display.c
|
Remove window.c, the one remaining function goes to display.c
|
||||||
Rework the modeline to look like Mg.
|
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
|
July 10, 2014 : emg 1.7
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|||||||
@@ -13,11 +13,6 @@ CFLAGS += -ffunction-sections -fdata-sections
|
|||||||
# This reduces code size significantly.
|
# This reduces code size significantly.
|
||||||
CFLAGS += -mips16
|
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
|
# with CFLAGS+= -ffunction-sections -fdata-sections
|
||||||
LDFLAGS += -Wl,--gc-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 "estruct.h"
|
||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
|
|
||||||
extern int getccol(int bflg);
|
extern int getccol(int);
|
||||||
extern void mlwrite();
|
extern void mlwrite();
|
||||||
extern int mlreplyt();
|
extern int mlreplyt();
|
||||||
|
|
||||||
int forwchar(int f, int n);
|
int forwchar(int, int);
|
||||||
int backchar(int f, int n);
|
int backchar(int, int);
|
||||||
int forwline(int f, int n);
|
int forwline(int, int);
|
||||||
int backline(int f, int n);
|
int backline(int, int);
|
||||||
int pagedown(int f, int n);
|
int pagedown(int, int);
|
||||||
int pageup(int f, int n);
|
int pageup(int, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine, given a pointer to a LINE, and the current cursor goal
|
* 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).
|
* PgDn. Scroll down (rows / 2).
|
||||||
* Just forwline(f, (ROWS -1))
|
* Just forwline(f, (rows / 2))
|
||||||
* Bound to C-V
|
* Bound to C-V
|
||||||
*/
|
*/
|
||||||
int pagedown(int f, int n)
|
int pagedown(int f, int n)
|
||||||
{
|
{
|
||||||
forwline(f, (ROWS - 1));
|
forwline(f, (rows / 2));
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PgUp. Scroll up (ROWS - 1).
|
* PgUp. Scroll up (rows / 2).
|
||||||
* Just backline(f, (ROWS -1))
|
* Just backline(f, (rows / 2))
|
||||||
* Bound to M-V
|
* Bound to M-V
|
||||||
*/
|
*/
|
||||||
int pageup(int f, int n)
|
int pageup(int f, int n)
|
||||||
{
|
{
|
||||||
backline(f, (ROWS - 1));
|
backline(f, (rows / 2));
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,93 +11,17 @@
|
|||||||
#include "estruct.h"
|
#include "estruct.h"
|
||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
|
|
||||||
extern int mlreply(char *prompt, char *buf, int nbuf);
|
extern int mlreply(char *, char *, int);
|
||||||
extern int readin(char fname[]);
|
extern int readin(char []);
|
||||||
extern void mlwrite();
|
extern void mlwrite();
|
||||||
extern void mlerase();
|
extern void mlerase();
|
||||||
extern int mlyesno(char *prompt);
|
extern int mlyesno(char *);
|
||||||
extern void lfree(LINE *lp);
|
extern void lfree(LINE *);
|
||||||
extern LINE *lalloc();
|
extern LINE *lalloc();
|
||||||
|
|
||||||
int swbuffer(BUFFER *bp);
|
int anycb(void);
|
||||||
int addline(char *text);
|
BUFFER *bfind(char *);
|
||||||
int anycb();
|
int bclear(BUFFER *);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look through the list of buffers. Return TRUE if there are any changed
|
* Look through the list of buffers. Return TRUE if there are any changed
|
||||||
@@ -105,91 +29,75 @@ int addline(char *text)
|
|||||||
* cares if the list of buffer names is hacked. Return FALSE if no buffers
|
* cares if the list of buffer names is hacked. Return FALSE if no buffers
|
||||||
* have been changed.
|
* have been changed.
|
||||||
*/
|
*/
|
||||||
int anycb()
|
int anycb(void)
|
||||||
{
|
{
|
||||||
BUFFER *bp;
|
BUFFER *bp;
|
||||||
|
|
||||||
bp = bheadp;
|
bp = bheadp;
|
||||||
while (bp != NULL)
|
while (bp != NULL) {
|
||||||
{
|
if ((bp->b_flag & BFTEMP) == 0 && (bp->b_flag & BFCHG) != 0)
|
||||||
if ((bp->b_flag & BFTEMP) == 0 && (bp->b_flag & BFCHG) != 0)
|
return (TRUE);
|
||||||
return (TRUE);
|
bp = bp->b_bufp;
|
||||||
bp = bp->b_bufp;
|
}
|
||||||
}
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a buffer, by name. Return a pointer to the BUFFER structure associated
|
* 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
|
* 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,
|
* buffer list), complain.
|
||||||
* create it. The "bflag" is the settings for the flags in in buffer.
|
|
||||||
*/
|
*/
|
||||||
BUFFER* bfind(char *bname, int cflag, int bflag)
|
BUFFER *
|
||||||
|
bfind(char *fname)
|
||||||
{
|
{
|
||||||
BUFFER *bp, *sb;
|
BUFFER *bp, *sb;
|
||||||
LINE *lp;
|
LINE *lp;
|
||||||
|
|
||||||
bp = bheadp;
|
bp = bheadp;
|
||||||
while (bp != 0)
|
while (bp != 0) {
|
||||||
{
|
if (strcmp(fname, bp->b_fname) == 0) {
|
||||||
if (strcmp(bname, bp->b_bname) == 0)
|
if ((bp->b_flag & BFTEMP) != 0) {
|
||||||
{
|
mlwrite("Cannot select builtin buffer");
|
||||||
if ((bp->b_flag & BFTEMP) != 0)
|
return (FALSE);
|
||||||
{
|
}
|
||||||
mlwrite ("Cannot select builtin buffer");
|
return (bp);
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
return (bp);
|
|
||||||
}
|
|
||||||
bp = bp->b_bufp;
|
|
||||||
}
|
}
|
||||||
if (cflag != FALSE)
|
bp = bp->b_bufp;
|
||||||
{
|
}
|
||||||
if ((bp = (BUFFER *) malloc(sizeof(BUFFER))) == NULL)
|
if ((bp = (BUFFER *) malloc(sizeof(BUFFER))) == NULL)
|
||||||
return (0);
|
return (FALSE);
|
||||||
if ((lp = lalloc(0)) == NULL)
|
if ((lp = lalloc(0)) == NULL) {
|
||||||
{
|
free(bp);
|
||||||
free(bp);
|
return (BUFFER *)0;
|
||||||
return (BUFFER*)0;
|
}
|
||||||
}
|
/* find the place in the list to insert this buffer */
|
||||||
/* find the place in the list to insert this buffer */
|
if (bheadp == NULL || strcmp(bheadp->b_fname, fname) > 0) {
|
||||||
if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0)
|
/* insert at the begining */
|
||||||
{
|
bp->b_bufp = bheadp;
|
||||||
/* insert at the begining */
|
bheadp = bp;
|
||||||
bp->b_bufp = bheadp;
|
} else {
|
||||||
bheadp = bp;
|
sb = bheadp;
|
||||||
}
|
while (sb->b_bufp != 0) {
|
||||||
else
|
if (strcmp(sb->b_bufp->b_fname, fname) > 0)
|
||||||
{
|
break;
|
||||||
sb = bheadp;
|
sb = sb->b_bufp;
|
||||||
while (sb->b_bufp != 0)
|
|
||||||
{
|
|
||||||
if (strcmp(sb->b_bufp->b_bname, bname) > 0)
|
|
||||||
break;
|
|
||||||
sb = sb->b_bufp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* and insert it */
|
|
||||||
bp->b_bufp = sb->b_bufp;
|
|
||||||
sb->b_bufp = bp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* and insert it */
|
||||||
|
bp->b_bufp = sb->b_bufp;
|
||||||
|
sb->b_bufp = bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and set up the other buffer fields */
|
||||||
|
bp->b_dotp = lp;
|
||||||
|
bp->b_doto = 0;
|
||||||
|
bp->b_markp = 0;
|
||||||
|
bp->b_marko = 0;
|
||||||
|
bp->b_flag = 0;
|
||||||
|
bp->b_linep = lp;
|
||||||
|
bp->b_lines = 1;
|
||||||
|
lp->l_fp = lp;
|
||||||
|
lp->l_bp = lp;
|
||||||
return (bp);
|
return (bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,28 +17,28 @@ extern int typeahead();
|
|||||||
extern int ctrlg();
|
extern int ctrlg();
|
||||||
extern int getccol();
|
extern int getccol();
|
||||||
|
|
||||||
void movecursor(int row, int col);
|
void movecursor(int, int);
|
||||||
void mlerase();
|
void mlerase();
|
||||||
int refresh();
|
int refresh();
|
||||||
void vtinit();
|
void vtinit();
|
||||||
void vttidy();
|
void vttidy();
|
||||||
void vtmove(int row, int col);
|
void vtmove(int, int);
|
||||||
void vtputc(int c);
|
void vtputc(int);
|
||||||
void vtpute(int c);
|
void vtpute(int);
|
||||||
int vtputs(const char *s);
|
int vtputs(const char *);
|
||||||
void vteeol();
|
void vteeol();
|
||||||
void update();
|
void update();
|
||||||
void updext();
|
void updext();
|
||||||
void updateline(int row, char vline[], char pline[], short *flags);
|
void updateline(int, char [], char [], short *);
|
||||||
void modeline(WINDOW *wp);
|
void modeline(WINDOW *);
|
||||||
void upmode();
|
void upmode();
|
||||||
int mlyesno(char *prompt);
|
int mlyesno(char *);
|
||||||
int mlreplyt(char *prompt, char *buf, int nbuf, char eolchar);
|
int mlreplyt(char *, char *, int, char);
|
||||||
int mlreply(char *prompt, char *buf, int nbuf);
|
int mlreply(char *, char *, int);
|
||||||
void mlwrite();
|
void mlwrite();
|
||||||
void mlputs(char *s);
|
void mlputs(char *);
|
||||||
void mlputi(int i, int r);
|
void mlputi(int, int);
|
||||||
void mlputli(long l, int r);
|
void mlputli(long, int);
|
||||||
|
|
||||||
typedef struct VIDEO {
|
typedef struct VIDEO {
|
||||||
short v_flag; /* Flags */
|
short v_flag; /* Flags */
|
||||||
@@ -1001,4 +1001,3 @@ void mlputli(long l, int r)
|
|||||||
(*term.t_putchar) ((int) (l % r) + '0');
|
(*term.t_putchar) ((int) (l % r) + '0');
|
||||||
++ttcol;
|
++ttcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,12 @@ KEYTAB keytab[] = {
|
|||||||
{META | 'S', forwsearch}, /* non-standard */
|
{META | 'S', forwsearch}, /* non-standard */
|
||||||
{META | 'V', pageup},
|
{META | 'V', pageup},
|
||||||
{META | 'W', copyregion},
|
{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},
|
{0x7F, backdel},
|
||||||
{META | '[', extendedcmd},
|
|
||||||
{META | 'O', extendedcmd},
|
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ int curcol; /* Cursor column */
|
|||||||
int thisflag; /* Flags, this command */
|
int thisflag; /* Flags, this command */
|
||||||
int lastflag; /* Flags, last command */
|
int lastflag; /* Flags, last command */
|
||||||
int curgoal; /* Goal for C-P, C-N */
|
int curgoal; /* Goal for C-P, C-N */
|
||||||
|
int rows; /* Screen rows for C-V, M-V */
|
||||||
WINDOW *curwp; /* Current window */
|
WINDOW *curwp; /* Current window */
|
||||||
BUFFER *curbp; /* Current buffer */
|
BUFFER *curbp; /* Current buffer */
|
||||||
WINDOW *wheadp; /* Head of list of windows */
|
WINDOW *wheadp; /* Head of list of windows */
|
||||||
BUFFER *bheadp; /* Head of list of buffers */
|
BUFFER *bheadp; /* Head of list of buffers */
|
||||||
BUFFER *blistp; /* Buffer for C-X C-B */
|
|
||||||
short *kbdmip; /* Input pointer for above */
|
short *kbdmip; /* Input pointer for above */
|
||||||
short *kbdmop; /* Output 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 thisflag; /* Flags, this command */
|
||||||
extern int lastflag; /* Flags, last command */
|
extern int lastflag; /* Flags, last command */
|
||||||
extern int curgoal; /* Goal for C-P, C-N */
|
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 WINDOW *curwp; /* Current window */
|
||||||
extern BUFFER *curbp; /* Current buffer */
|
extern BUFFER *curbp; /* Current buffer */
|
||||||
extern WINDOW *wheadp; /* Head of list of windows */
|
extern WINDOW *wheadp; /* Head of list of windows */
|
||||||
extern BUFFER *bheadp; /* Head of list of buffers */
|
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 *kbdmip; /* Input pointer for above */
|
||||||
extern short *kbdmop; /* Output pointer for above */
|
extern short *kbdmop; /* Output pointer for above */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* terminal table defined only in TERM.C */
|
|
||||||
|
|
||||||
#ifndef termdef
|
|
||||||
extern TERM term; /* Terminal information */
|
extern TERM term; /* Terminal information */
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -44,11 +44,9 @@ extern int killtext(); /* Kill forward */
|
|||||||
extern int yank(); /* Yank back from killbuffer */
|
extern int yank(); /* Yank back from killbuffer */
|
||||||
extern int killregion(); /* Kill region */
|
extern int killregion(); /* Kill region */
|
||||||
extern int copyregion(); /* Copy region to kill buffer */
|
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 setline(); /* go to a numbered line */
|
||||||
extern int deskey(); /* describe a key's binding */
|
extern int deskey(); /* describe a key's binding */
|
||||||
extern int insfile(); /* insert a file */
|
extern int insfile(); /* insert a file */
|
||||||
extern int forwhunt(); /* hunt forward for next match */
|
extern int forwhunt(); /* hunt forward for next match */
|
||||||
extern int backhunt(); /* hunt backwards 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 */
|
extern int showversion(); /* show emacs version */
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" Basic emg man page.
|
.\" Basic emg man page.
|
||||||
.\" As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
|
.\" As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
|
||||||
.\"
|
.\"
|
||||||
.Dd August 9, 2014
|
.Dd August 9, 2015
|
||||||
.Os
|
.Os
|
||||||
.Dt EMG 1
|
.Dt EMG 1
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
emg keybindings (August 9, 2014)
|
emg keybindings (August 9, 2015)
|
||||||
Based on Ersatz Emacs (2000/09/14)
|
Based on Ersatz Emacs (2000/09/14)
|
||||||
|
|
||||||
M- means to use the <ESC> key prior to using another key
|
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 CTRL 0x0100 /* Control flag, or'ed in */
|
||||||
#define META 0x0200 /* Meta flag, or'ed in */
|
#define META 0x0200 /* Meta flag, or'ed in */
|
||||||
#define CTLX 0x0400 /* ^X 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 FALSE 0 /* False, no, bad, etc */
|
||||||
#define TRUE 1 /* True, yes, good, etc */
|
#define TRUE 1 /* True, yes, good, etc */
|
||||||
@@ -31,35 +32,6 @@
|
|||||||
#define CFCPCN 0x0001 /* Last command was C-P, C-N */
|
#define CFCPCN 0x0001 /* Last command was C-P, C-N */
|
||||||
#define CFKILL 0x0002 /* Last command was a kill */
|
#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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* safe store for the dot and mark in the header. The text for the buffer is
|
||||||
* the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
|
* kept in a circularly linked list of lines, with a pointer to the header
|
||||||
* the buffer is kept in a circularly linked list of lines, with a pointer to
|
* line in "b_linep".
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
typedef struct BUFFER
|
typedef struct BUFFER
|
||||||
{
|
{
|
||||||
@@ -110,11 +79,8 @@ typedef struct BUFFER
|
|||||||
struct LINE *b_markp; /* The same as the above two, */
|
struct LINE *b_markp; /* The same as the above two, */
|
||||||
long b_marko; /* but for the "mark" */
|
long b_marko; /* but for the "mark" */
|
||||||
struct LINE *b_linep; /* Link to the header LINE */
|
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_flag; /* Flags */
|
||||||
char b_fname[NFILEN]; /* File name */
|
char b_fname[NFILEN]; /* File name */
|
||||||
char b_bname[NBUFN]; /* Buffer name */
|
|
||||||
int b_lines; /* Number of lines in file */
|
int b_lines; /* Number of lines in file */
|
||||||
} BUFFER;
|
} BUFFER;
|
||||||
|
|
||||||
|
|||||||
@@ -9,40 +9,37 @@
|
|||||||
#include "estruct.h"
|
#include "estruct.h"
|
||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
|
|
||||||
extern int mlreply(char *prompt, char *buf, int nbuf);
|
extern int mlreply(char *, char *, int);
|
||||||
extern int swbuffer(BUFFER *bp);
|
|
||||||
extern void mlwrite();
|
extern void mlwrite();
|
||||||
extern int bclear(BUFFER *bp);
|
extern int bclear(BUFFER *);
|
||||||
extern int ffropen(char *fn);
|
extern int ffropen(char *);
|
||||||
extern int ffgetline(char buf[], int nbuf);
|
extern int ffgetline(char [], int);
|
||||||
extern int ffwopen(char *fn);
|
extern int ffwopen(char *);
|
||||||
extern int ffclose();
|
extern int ffclose();
|
||||||
extern int ffputline(char buf[], int nbuf);
|
extern int ffputline(char [], int);
|
||||||
extern BUFFER *bfind();
|
extern BUFFER *bfind();
|
||||||
extern LINE *lalloc();
|
extern LINE *lalloc();
|
||||||
|
|
||||||
int fileread(int f, int n);
|
int fileread(int, int);
|
||||||
int insfile(int f, int n);
|
int insfile(int, int);
|
||||||
int getfile(char fname[]);
|
int readin(char []);
|
||||||
int readin(char fname[]);
|
int filewrite(int, int);
|
||||||
void makename(char bname[], char fname[]);
|
int filesave(int, int);
|
||||||
int filewrite(int f, int n);
|
int writeout(char *);
|
||||||
int filesave(int f, int n);
|
int filename(int, int);
|
||||||
int writeout(char *fn);
|
int ifile(char []);
|
||||||
int filename(int f, int n);
|
|
||||||
int ifile(char fname[]);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a file into the current buffer. This is really easy; all you do it
|
* 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
|
* 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 fileread(int f, int n)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
char fname[NFILEN];
|
char fname[NFILEN];
|
||||||
|
|
||||||
if ((s = mlreply("Read file: ", fname, NFILEN)) != TRUE)
|
if ((s = mlreply("Open file: ", fname, NFILEN)) != TRUE)
|
||||||
return (s);
|
return (s);
|
||||||
return (readin(fname));
|
return (readin(fname));
|
||||||
}
|
}
|
||||||
@@ -62,65 +59,6 @@ int insfile(int f, int n)
|
|||||||
return (ifile(fname));
|
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
|
* 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
|
* 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_doto = 0;
|
||||||
wp->w_markp = NULL;
|
wp->w_markp = NULL;
|
||||||
wp->w_marko = 0;
|
wp->w_marko = 0;
|
||||||
|
wp->w_dotline = 0;
|
||||||
wp->w_flag |= WFMODE | WFHARD;
|
wp->w_flag |= WFMODE | WFHARD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,27 +143,6 @@ int readin(char fname[])
|
|||||||
return (TRUE);
|
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
|
* 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.
|
* 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 */
|
if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes */
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
if (curbp->b_fname[0] == 0)
|
if (curbp->b_fname[0] == '\0')
|
||||||
filename(f, n); /* Must have a name */
|
filename(f, n); /* Must have a name */
|
||||||
if ((s = writeout(curbp->b_fname)) == TRUE)
|
if ((s = writeout(curbp->b_fname)) == TRUE)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
|
|
||||||
extern void mlwrite();
|
extern void mlwrite();
|
||||||
|
|
||||||
int ffropen(char *fn);
|
int ffropen(char *);
|
||||||
int ffwopen(char *fn);
|
int ffwopen(char *);
|
||||||
int ffclose();
|
int ffclose();
|
||||||
int ffputline(char buf[], int nbuf);
|
int ffputline(char [], int);
|
||||||
int ffgetline(char buf[], int nbuf);
|
int ffgetline(char [], int);
|
||||||
|
|
||||||
FILE *ffp; /* File pointer, all functions */
|
FILE *ffp; /* File pointer, all functions */
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,6 @@
|
|||||||
* and window structures, to make sure that the necessary updating gets done.
|
* 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
|
* There are routines in this file that handle the kill buffer too. It isn't
|
||||||
* here for any good reason.
|
* 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) */
|
#include <stdlib.h> /* malloc(3) */
|
||||||
@@ -19,18 +13,18 @@
|
|||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
|
|
||||||
extern void mlwrite();
|
extern void mlwrite();
|
||||||
extern int backchar(int f, int n);
|
extern int backchar(int, int);
|
||||||
|
|
||||||
LINE* lalloc(int used);
|
LINE* lalloc(int);
|
||||||
void lfree(LINE *lp);
|
void lfree(LINE *);
|
||||||
void lchange(int flag);
|
void lchange(int);
|
||||||
int linsert(int n, int c);
|
int linsert(int, int);
|
||||||
int lnewline();
|
int lnewline();
|
||||||
int ldelete(int n, int kflag);
|
int ldelete(int, int);
|
||||||
int ldelnewline();
|
int ldelnewline();
|
||||||
void kdelete();
|
void kdelete();
|
||||||
int kinsert(int c);
|
int kinsert(int);
|
||||||
int kremove(int n);
|
int kremove(int);
|
||||||
|
|
||||||
#define NBLOCK 16 /* Line block chunk size */
|
#define NBLOCK 16 /* Line block chunk size */
|
||||||
#define KBLOCK 1024 /* Kill buffer block 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
|
* 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.
|
* message in the message line if no space.
|
||||||
*/
|
*/
|
||||||
LINE* lalloc(int used)
|
LINE *
|
||||||
|
lalloc(int used)
|
||||||
{
|
{
|
||||||
LINE *lp;
|
LINE *lp;
|
||||||
int size;
|
int size;
|
||||||
@@ -69,7 +64,8 @@ LINE* lalloc(int used)
|
|||||||
* might be in. Release the memory. The buffers are updated too; the magic
|
* might be in. Release the memory. The buffers are updated too; the magic
|
||||||
* conditions described in the above comments don't hold here
|
* conditions described in the above comments don't hold here
|
||||||
*/
|
*/
|
||||||
void lfree(LINE *lp)
|
void
|
||||||
|
lfree(LINE *lp)
|
||||||
{
|
{
|
||||||
BUFFER *bp;
|
BUFFER *bp;
|
||||||
WINDOW *wp;
|
WINDOW *wp;
|
||||||
@@ -92,23 +88,17 @@ void lfree(LINE *lp)
|
|||||||
wp = wp->w_wndp;
|
wp = wp->w_wndp;
|
||||||
}
|
}
|
||||||
bp = bheadp;
|
bp = bheadp;
|
||||||
while (bp != NULL)
|
while (bp != NULL) {
|
||||||
{
|
if (bp->b_dotp == lp) {
|
||||||
if (bp->b_nwnd == 0)
|
bp->b_dotp = lp->l_fp;
|
||||||
{
|
bp->b_doto = 0;
|
||||||
if (bp->b_dotp == lp)
|
|
||||||
{
|
|
||||||
bp->b_dotp = lp->l_fp;
|
|
||||||
bp->b_doto = 0;
|
|
||||||
}
|
|
||||||
if (bp->b_markp == lp)
|
|
||||||
{
|
|
||||||
bp->b_markp = lp->l_fp;
|
|
||||||
bp->b_marko = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bp = bp->b_bufp;
|
|
||||||
}
|
}
|
||||||
|
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;
|
lp->l_bp->l_fp = lp->l_fp;
|
||||||
lp->l_fp->l_bp = lp->l_bp;
|
lp->l_fp->l_bp = lp->l_bp;
|
||||||
free((char *) lp);
|
free((char *) lp);
|
||||||
@@ -117,28 +107,24 @@ void lfree(LINE *lp)
|
|||||||
/*
|
/*
|
||||||
* This routine gets called when a character is changed in place in the
|
* 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
|
* 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
|
* window system. The flag used is passed as an argument. Set MODE if the
|
||||||
* being displayed in more than 1 window we change EDIT t HARD. Set MODE if
|
* mode line needs to be updated (the "**" has to be set).
|
||||||
* the mode line needs to be updated (the "*" has to be set).
|
|
||||||
*/
|
*/
|
||||||
void lchange(int flag)
|
void
|
||||||
|
lchange(int flag)
|
||||||
{
|
{
|
||||||
WINDOW *wp;
|
WINDOW *wp;
|
||||||
|
|
||||||
if (curbp->b_nwnd != 1) /* Ensure hard */
|
if ((curbp->b_flag & BFCHG) == 0) { /* First change, so */
|
||||||
flag = WFHARD;
|
flag |= WFMODE; /* update mode lines */
|
||||||
if ((curbp->b_flag & BFCHG) == 0)
|
curbp->b_flag |= BFCHG;
|
||||||
{ /* First change, so */
|
}
|
||||||
flag |= WFMODE; /* update mode lines */
|
|
||||||
curbp->b_flag |= BFCHG;
|
|
||||||
}
|
|
||||||
wp = wheadp;
|
wp = wheadp;
|
||||||
while (wp != NULL)
|
while (wp != NULL) {
|
||||||
{
|
if (wp->w_bufp == curbp)
|
||||||
if (wp->w_bufp == curbp)
|
wp->w_flag |= flag;
|
||||||
wp->w_flag |= flag;
|
wp = wp->w_wndp;
|
||||||
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
|
* greater than the place where you did the insert. Return TRUE if all is
|
||||||
* well, and FALSE on errors
|
* well, and FALSE on errors
|
||||||
*/
|
*/
|
||||||
int linsert(int n, int c)
|
int
|
||||||
|
linsert(int n, int c)
|
||||||
{
|
{
|
||||||
WINDOW *wp;
|
WINDOW *wp;
|
||||||
LINE *lp1, *lp2, *lp3;
|
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
|
* update of dot and mark is a bit easier then in the above case, because the
|
||||||
* split forces more updating.
|
* split forces more updating.
|
||||||
*/
|
*/
|
||||||
int lnewline()
|
int
|
||||||
|
lnewline()
|
||||||
{
|
{
|
||||||
WINDOW *wp;
|
WINDOW *wp;
|
||||||
char *cp1, *cp2;
|
char *cp1, *cp2;
|
||||||
@@ -296,7 +284,8 @@ int lnewline()
|
|||||||
* deleted, and FALSE if they were not (because dot ran into the end of the
|
* 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.
|
* 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;
|
LINE *dotp;
|
||||||
WINDOW *wp;
|
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
|
* require that lines be moved about in memory. Return FALSE on error and TRUE
|
||||||
* if all looks ok. Called by "ldelete" only.
|
* if all looks ok. Called by "ldelete" only.
|
||||||
*/
|
*/
|
||||||
int ldelnewline()
|
int
|
||||||
|
ldelnewline()
|
||||||
{
|
{
|
||||||
LINE *lp1, *lp2, *lp3;
|
LINE *lp1, *lp2, *lp3;
|
||||||
WINDOW *wp;
|
WINDOW *wp;
|
||||||
@@ -457,10 +447,10 @@ int ldelnewline()
|
|||||||
* new kill context is being created. The kill buffer array is released, just
|
* new kill context is being created. The kill buffer array is released, just
|
||||||
* in case the buffer has grown to immense size. No errors.
|
* in case the buffer has grown to immense size. No errors.
|
||||||
*/
|
*/
|
||||||
void kdelete()
|
void
|
||||||
|
kdelete()
|
||||||
{
|
{
|
||||||
if (kbufp != NULL)
|
if (kbufp != NULL) {
|
||||||
{
|
|
||||||
free((char *) kbufp);
|
free((char *) kbufp);
|
||||||
kbufp = NULL;
|
kbufp = NULL;
|
||||||
kused = 0;
|
kused = 0;
|
||||||
@@ -474,7 +464,8 @@ void kdelete()
|
|||||||
* put something in the kill buffer you are going to put more stuff there too
|
* 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.
|
* later. Return TRUE if all is well, and FALSE on errors.
|
||||||
*/
|
*/
|
||||||
int kinsert(int c)
|
int
|
||||||
|
kinsert(int c)
|
||||||
{
|
{
|
||||||
char *nbufp;
|
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
|
* "n" is off the end, it returns "-1". This lets the caller just scan along
|
||||||
* until it gets a "-1" back.
|
* until it gets a "-1" back.
|
||||||
*/
|
*/
|
||||||
int kremove(int n)
|
int
|
||||||
|
kremove(int n)
|
||||||
{
|
{
|
||||||
if (n >= kused)
|
if (n >= kused)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|||||||
@@ -22,186 +22,154 @@ extern void vttidy();
|
|||||||
extern void update();
|
extern void update();
|
||||||
extern void mlerase();
|
extern void mlerase();
|
||||||
extern void mlwrite();
|
extern void mlwrite();
|
||||||
extern int mlyesno(char *prompt);
|
extern int mlyesno(char *);
|
||||||
extern void makename(char bname[], char fname[]);
|
extern int readin(char []);
|
||||||
extern int readin(char fname[]);
|
extern int linsert(int, int);
|
||||||
extern int linsert(int f, int n);
|
extern int anycb(void);
|
||||||
extern int anycb();
|
extern BUFFER *bfind(char *);
|
||||||
extern BUFFER *bfind();
|
|
||||||
|
|
||||||
void edinit(char bname[]);
|
void edinit(char []);
|
||||||
int execute(int c, int f, int n);
|
int execute(int, int, int);
|
||||||
int getkey();
|
int getkey(void);
|
||||||
int getctl();
|
int getctl(void);
|
||||||
int quickexit(int f, int n);
|
int quit(int, int);
|
||||||
int quit(int f, int n);
|
int ctlxlp(int, int);
|
||||||
int ctlxlp(int f, int n);
|
int ctlxrp(int, int);
|
||||||
int ctlxrp(int f, int n);
|
int ctlxe(int, int);
|
||||||
int ctlxe(int f, int n);
|
int ctrlg(int, int);
|
||||||
int ctrlg(int f, int n);
|
|
||||||
int extendedcmd(int f, int n);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
BUFFER *bp;
|
BUFFER *bp;
|
||||||
char bname[NBUFN]; /* buffer name of file to read */
|
char fname[NFILEN];
|
||||||
int c, f, n, mflag;
|
int c, f, n, mflag;
|
||||||
int ffile; /* first file flag */
|
|
||||||
int basec; /* c stripped of meta character */
|
int basec; /* c stripped of meta character */
|
||||||
|
|
||||||
/* initialize the editor and process the startup file */
|
/* In place of getopt() */
|
||||||
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 */
|
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
(void) fprintf(stderr, "Can only edit one file at a time\n");
|
(void) fprintf(stderr, "usage: emg [file]\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (argc == 2) {
|
} else if (argc == 2) {
|
||||||
/* set up a buffer for this file */
|
strncpy(fname, argv[1], NFILEN);
|
||||||
makename(bname, argv[1]);
|
} else {
|
||||||
|
strncpy(fname, "*scratch*", NFILEN);
|
||||||
|
}
|
||||||
|
|
||||||
/* if this is the first file, read it in */
|
/* initialize the editor and process the startup file */
|
||||||
if (ffile)
|
getwinsize(); /* Find out the "real" screen size */
|
||||||
{
|
edinit(fname); /* Buffers, windows */
|
||||||
bp = curbp;
|
vtinit(); /* Displays */
|
||||||
makename(bname, argv[1]);
|
update(); /* Let the user know we are here */
|
||||||
strncpy(bp->b_bname, bname, NBUFN);
|
|
||||||
strncpy(bp->b_fname, argv[1], NFILEN);
|
/* Read in the file given on the command line */
|
||||||
if (readin(argv[1]) == ABORT)
|
if (argc == 2) {
|
||||||
{
|
bp = curbp;
|
||||||
strncpy(bp->b_bname, "main", 5);
|
if (readin(argv[1]) == ABORT)
|
||||||
strncpy(bp->b_fname, "", 1);
|
strncpy(fname, "*scratch*", NFILEN);
|
||||||
}
|
bp->b_dotp = bp->b_linep;
|
||||||
bp->b_dotp = bp->b_linep;
|
bp->b_doto = 0;
|
||||||
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 */
|
/* setup to process commands */
|
||||||
lastflag = 0; /* Fake last flags */
|
lastflag = 0; /* Fake last flags */
|
||||||
curwp->w_flag |= WFMODE; /* and force an update */
|
curwp->w_flag |= WFMODE; /* and force an update */
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
update(); /* Fix up the screen */
|
update(); /* Fix up the screen */
|
||||||
c = getkey();
|
c = getkey();
|
||||||
if (mpresf != FALSE)
|
if (mpresf != FALSE) {
|
||||||
{
|
mlerase();
|
||||||
mlerase();
|
update();
|
||||||
update();
|
}
|
||||||
}
|
|
||||||
f = FALSE;
|
f = FALSE;
|
||||||
n = 1;
|
n = 1;
|
||||||
|
|
||||||
/* do META-# processing if needed */
|
/* do META-# processing if needed */
|
||||||
|
|
||||||
basec = c & ~META; /* strip meta char off if there */
|
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 */
|
||||||
f = TRUE; /* there is a # arg */
|
n = 0; /* start with a zero default */
|
||||||
n = 0; /* start with a zero default */
|
mflag = 1; /* current minus flag */
|
||||||
mflag = 1; /* current minus flag */
|
c = basec; /* strip the META */
|
||||||
c = basec; /* strip the META */
|
while ((c >= '0' && c <= '9') || (c == '-')) {
|
||||||
while ((c >= '0' && c <= '9') || (c == '-'))
|
if (c == '-') {
|
||||||
{
|
/* already hit a minus or digit? */
|
||||||
if (c == '-')
|
if ((mflag == -1) || (n != 0))
|
||||||
{
|
break;
|
||||||
/* already hit a minus or digit? */
|
mflag = -1;
|
||||||
if ((mflag == -1) || (n != 0))
|
} else
|
||||||
break;
|
n = n * 10 + (c - '0');
|
||||||
mflag = -1;
|
if ((n == 0) && (mflag == -1)) /* lonely - */
|
||||||
}
|
mlwrite("Arg:");
|
||||||
else
|
else
|
||||||
n = n * 10 + (c - '0');
|
mlwrite("Arg: %d", n * mflag);
|
||||||
if ((n == 0) && (mflag == -1)) /* lonely - */
|
|
||||||
mlwrite("Arg:");
|
|
||||||
else
|
|
||||||
mlwrite("Arg: %d", n * mflag);
|
|
||||||
|
|
||||||
c = getkey(); /* get the next key */
|
c = getkey(); /* get the next key */
|
||||||
}
|
|
||||||
n = n * mflag; /* figure in the sign */
|
|
||||||
}
|
}
|
||||||
|
n = n * mflag; /* figure in the sign */
|
||||||
|
}
|
||||||
|
|
||||||
/* do ^U repeat argument processing */
|
/* do ^U repeat argument processing */
|
||||||
|
if (c == (CTRL | 'U')) { /* ^U, start argument */
|
||||||
if (c == (CTRL | 'U'))
|
f = TRUE;
|
||||||
{ /* ^U, start argument */
|
n = 4; /* with argument of 4 */
|
||||||
f = TRUE;
|
mflag = 0; /* that can be discarded */
|
||||||
n = 4; /* with argument of 4 */
|
mlwrite("Arg: 4");
|
||||||
mflag = 0; /* that can be discarded */
|
while (((c = getkey()) >= '0')
|
||||||
mlwrite("Arg: 4");
|
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-'))) {
|
||||||
while (((c = getkey ()) >= '0')
|
if (c == (CTRL | 'U'))
|
||||||
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-')))
|
n = n * 4;
|
||||||
{
|
|
||||||
if (c == (CTRL | 'U'))
|
|
||||||
n = n * 4;
|
|
||||||
/*
|
|
||||||
* If dash, and start of argument string, set arg.
|
|
||||||
* to -1. Otherwise, insert it.
|
|
||||||
*/
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
n = 0;
|
|
||||||
mflag = 1;
|
|
||||||
}
|
|
||||||
n = 10 * n + c - '0';
|
|
||||||
}
|
|
||||||
mlwrite("Arg: %d", (mflag >= 0) ? n : (n ? -n : -1));
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Make arguments preceded by a minus sign negative and change
|
* If dash, and start of argument string, set arg.
|
||||||
* the special argument "^U -" to an effective "^U -1".
|
* to -1. Otherwise, insert it.
|
||||||
*/
|
*/
|
||||||
if (mflag == -1)
|
else if (c == '-') {
|
||||||
{
|
if (mflag)
|
||||||
if (n == 0)
|
break;
|
||||||
n++;
|
n = 0;
|
||||||
n = -n;
|
mflag = -1;
|
||||||
|
/*
|
||||||
|
* If first digit entered, replace previous argument
|
||||||
|
* with digit and set sign. Otherwise, append to arg.
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
if (!mflag) {
|
||||||
|
n = 0;
|
||||||
|
mflag = 1;
|
||||||
}
|
}
|
||||||
|
n = 10 * n + c - '0';
|
||||||
|
}
|
||||||
|
mlwrite("Arg: %d", (mflag >= 0) ? n : (n ? -n : -1));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Make arguments preceded by a minus sign negative and change
|
||||||
|
* the special argument "^U -" to an effective "^U -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 = CTLX | getctl ();
|
c = METE | getctl();
|
||||||
if (kbdmip != NULL)
|
else if (c == (CTRL | 'X')) /* ^X is a prefix */
|
||||||
{ /* Save macro strokes */
|
c = CTLX | getctl();
|
||||||
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6])
|
|
||||||
{
|
if (kbdmip != NULL) { /* Save macro strokes */
|
||||||
ctrlg(FALSE, 0);
|
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6]) {
|
||||||
goto loop;
|
ctrlg(FALSE, 0);
|
||||||
}
|
goto loop;
|
||||||
if (f != FALSE)
|
|
||||||
{
|
|
||||||
*kbdmip++ = (CTRL | 'U');
|
|
||||||
*kbdmip++ = n;
|
|
||||||
}
|
|
||||||
*kbdmip++ = c;
|
|
||||||
}
|
}
|
||||||
|
if (f != FALSE) {
|
||||||
|
*kbdmip++ = (CTRL | 'U');
|
||||||
|
*kbdmip++ = n;
|
||||||
|
}
|
||||||
|
*kbdmip++ = c;
|
||||||
|
}
|
||||||
execute(c, f, n); /* Do it */
|
execute(c, f, n); /* Do it */
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
@@ -211,22 +179,21 @@ main(int argc, char *argv[])
|
|||||||
* as an argument, because the main routine may have been told to read in a
|
* 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.
|
* file by default, and we want the buffer name to be right.
|
||||||
*/
|
*/
|
||||||
void edinit(char bname[])
|
void
|
||||||
|
edinit(char fname[])
|
||||||
{
|
{
|
||||||
BUFFER *bp;
|
BUFFER *bp;
|
||||||
WINDOW *wp;
|
WINDOW *wp;
|
||||||
|
|
||||||
bp = bfind(bname, TRUE, 0); /* First buffer */
|
bp = bfind(fname);
|
||||||
blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */
|
wp = (WINDOW *) malloc(sizeof(WINDOW));
|
||||||
wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
|
if (bp == NULL || wp == NULL)
|
||||||
if (bp == NULL || wp == NULL || blistp == NULL)
|
exit(1);
|
||||||
exit (1);
|
|
||||||
curbp = bp; /* Make this current */
|
curbp = bp; /* Make this current */
|
||||||
wheadp = wp;
|
wheadp = wp;
|
||||||
curwp = wp;
|
curwp = wp;
|
||||||
wp->w_wndp = NULL; /* Initialize window */
|
wp->w_wndp = NULL; /* Initialize window */
|
||||||
wp->w_bufp = bp;
|
wp->w_bufp = bp;
|
||||||
bp->b_nwnd = 1; /* Displayed */
|
|
||||||
wp->w_linep = bp->b_linep;
|
wp->w_linep = bp->b_linep;
|
||||||
wp->w_dotp = bp->b_linep;
|
wp->w_dotp = bp->b_linep;
|
||||||
wp->w_doto = 0;
|
wp->w_doto = 0;
|
||||||
@@ -244,39 +211,36 @@ void edinit(char bname[])
|
|||||||
* and arranges to move it to the "lastflag", so that the next command can
|
* and arranges to move it to the "lastflag", so that the next command can
|
||||||
* look at it. Return the status of command.
|
* 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;
|
KEYTAB *ktp;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
ktp = &keytab[0]; /* Look in key table */
|
ktp = &keytab[0]; /* Look in key table */
|
||||||
while (ktp->k_fp != NULL)
|
while (ktp->k_fp != NULL) {
|
||||||
{
|
if (ktp->k_code == c) {
|
||||||
if (ktp->k_code == c)
|
thisflag = 0;
|
||||||
{
|
status = (*ktp->k_fp) (f, n);
|
||||||
thisflag = 0;
|
|
||||||
status = (*ktp->k_fp) (f, n);
|
|
||||||
lastflag = thisflag;
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
++ktp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((c >= 0x20 && c <= 0x7E) /* Self inserting */
|
|
||||||
|| (c >= 0xA0 && c <= 0xFE))
|
|
||||||
{
|
|
||||||
if (n <= 0)
|
|
||||||
{ /* Fenceposts */
|
|
||||||
lastflag = 0;
|
|
||||||
return (n < 0 ? FALSE : TRUE);
|
|
||||||
}
|
|
||||||
thisflag = 0; /* For the future */
|
|
||||||
|
|
||||||
status = linsert(n, c);
|
|
||||||
|
|
||||||
lastflag = thisflag;
|
lastflag = thisflag;
|
||||||
return (status);
|
return (status);
|
||||||
}
|
}
|
||||||
|
++ktp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c >= 0x20 && c <= 0x7E) /* Self inserting */
|
||||||
|
|| (c >= 0xA0 && c <= 0xFE)) {
|
||||||
|
if (n <= 0) { /* Fenceposts */
|
||||||
|
lastflag = 0;
|
||||||
|
return (n < 0 ? FALSE : TRUE);
|
||||||
|
}
|
||||||
|
thisflag = 0; /* For the future */
|
||||||
|
|
||||||
|
status = linsert(n, c);
|
||||||
|
|
||||||
|
lastflag = thisflag;
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
mlwrite("\007[Key not bound]"); /* complain */
|
mlwrite("\007[Key not bound]"); /* complain */
|
||||||
lastflag = 0; /* Fake last flags */
|
lastflag = 0; /* Fake last flags */
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
@@ -286,17 +250,17 @@ int execute(int c, int f, int n)
|
|||||||
* Read in a key. Do the standard keyboard preprocessing. Convert the keys to
|
* Read in a key. Do the standard keyboard preprocessing. Convert the keys to
|
||||||
* the internal character set.
|
* the internal character set.
|
||||||
*/
|
*/
|
||||||
int getkey()
|
int
|
||||||
|
getkey(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = (*term.t_getchar) ();
|
c = (*term.t_getchar) ();
|
||||||
|
|
||||||
if (c == METACH)
|
if (c == METACH) { /* Apply M- prefix */
|
||||||
{ /* Apply M- prefix */
|
c = getctl();
|
||||||
c = getctl ();
|
return (META | c);
|
||||||
return (META | c);
|
}
|
||||||
}
|
|
||||||
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
|
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
|
||||||
c = CTRL | (c + '@');
|
c = CTRL | (c + '@');
|
||||||
return (c);
|
return (c);
|
||||||
@@ -305,11 +269,12 @@ int getkey()
|
|||||||
/*
|
/*
|
||||||
* Get a key. Apply control modifications to the read key.
|
* Get a key. Apply control modifications to the read key.
|
||||||
*/
|
*/
|
||||||
int getctl()
|
int
|
||||||
|
getctl()
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = (*term.t_getchar) ();
|
c = (*term.t_getchar)();
|
||||||
if (c >= 'a' && c <= 'z') /* Force to upper */
|
if (c >= 'a' && c <= 'z') /* Force to upper */
|
||||||
c -= 0x20;
|
c -= 0x20;
|
||||||
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
|
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
|
||||||
@@ -317,44 +282,21 @@ int getctl()
|
|||||||
return (c);
|
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
|
* 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".
|
* 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;
|
int s;
|
||||||
|
|
||||||
if (f != FALSE /* Argument forces it */
|
if (f != FALSE /* Argument forces it */
|
||||||
|| anycb () == FALSE /* All buffers clean */
|
|| anycb() == FALSE /* All buffers clean */
|
||||||
|| (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE)
|
|| (s = mlyesno("Quit without saving")) == TRUE) {
|
||||||
{
|
vttidy();
|
||||||
vttidy();
|
exit(0);
|
||||||
exit (0);
|
}
|
||||||
}
|
|
||||||
mlwrite("");
|
mlwrite("");
|
||||||
return (s);
|
return (s);
|
||||||
}
|
}
|
||||||
@@ -363,13 +305,13 @@ int quit(int f, int n)
|
|||||||
* Begin a keyboard macro. Error if not at the top level in keyboard
|
* Begin a keyboard macro. Error if not at the top level in keyboard
|
||||||
* processing. Set up variables and return.
|
* processing. Set up variables and return.
|
||||||
*/
|
*/
|
||||||
int ctlxlp(int f, int n)
|
int
|
||||||
|
ctlxlp(int f, int n)
|
||||||
{
|
{
|
||||||
if (kbdmip != NULL || kbdmop != NULL)
|
if (kbdmip != NULL || kbdmop != NULL) {
|
||||||
{
|
mlwrite("Not now");
|
||||||
mlwrite("Not now");
|
return (FALSE);
|
||||||
return (FALSE);
|
}
|
||||||
}
|
|
||||||
mlwrite("[Start macro]");
|
mlwrite("[Start macro]");
|
||||||
kbdmip = &kbdm[0];
|
kbdmip = &kbdm[0];
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
@@ -379,13 +321,13 @@ int ctlxlp(int f, int n)
|
|||||||
* End keyboard macro. Check for the same limit conditions as the above
|
* End keyboard macro. Check for the same limit conditions as the above
|
||||||
* routine. Set up the variables and return to the caller.
|
* routine. Set up the variables and return to the caller.
|
||||||
*/
|
*/
|
||||||
int ctlxrp(int f, int n)
|
int
|
||||||
|
ctlxrp(int f, int n)
|
||||||
{
|
{
|
||||||
if (kbdmip == NULL)
|
if (kbdmip == NULL) {
|
||||||
{
|
mlwrite("Not now");
|
||||||
mlwrite("Not now");
|
return (FALSE);
|
||||||
return (FALSE);
|
}
|
||||||
}
|
|
||||||
mlwrite("[End macro]");
|
mlwrite("[End macro]");
|
||||||
kbdmip = NULL;
|
kbdmip = NULL;
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
@@ -395,36 +337,31 @@ int ctlxrp(int f, int n)
|
|||||||
* Execute a macro. The command argument is the number of times to loop. Quit
|
* 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.
|
* 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;
|
int c, af, an, s;
|
||||||
|
|
||||||
if (kbdmip != NULL || kbdmop != NULL)
|
if (kbdmip != NULL || kbdmop != NULL) {
|
||||||
{
|
mlwrite("No macro defined");
|
||||||
mlwrite("No macro defined");
|
return (FALSE);
|
||||||
return (FALSE);
|
}
|
||||||
}
|
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
do
|
do {
|
||||||
{
|
kbdmop = &kbdm[0];
|
||||||
kbdmop = &kbdm[0];
|
do {
|
||||||
do
|
af = FALSE;
|
||||||
{
|
an = 1;
|
||||||
af = FALSE;
|
if ((c = *kbdmop++) == (CTRL | 'U')) {
|
||||||
an = 1;
|
af = TRUE;
|
||||||
if ((c = *kbdmop++) == (CTRL | 'U'))
|
an = *kbdmop++;
|
||||||
{
|
c = *kbdmop++;
|
||||||
af = TRUE;
|
}
|
||||||
an = *kbdmop++;
|
s = TRUE;
|
||||||
c = *kbdmop++;
|
} while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
|
||||||
}
|
kbdmop = NULL;
|
||||||
s = TRUE;
|
} while (s == TRUE && --n);
|
||||||
}
|
|
||||||
while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
|
|
||||||
kbdmop = NULL;
|
|
||||||
}
|
|
||||||
while (s == TRUE && --n);
|
|
||||||
return (s);
|
return (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,45 +369,18 @@ int ctlxe(int f, int n)
|
|||||||
* Abort. Beep the beeper. Kill off any keyboard macro, etc., that is in
|
* 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.
|
* 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) ();
|
(*term.t_beep) ();
|
||||||
if (kbdmip != NULL)
|
if (kbdmip != NULL) {
|
||||||
{
|
kbdm[0] = (CTLX | ')');
|
||||||
kbdm[0] = (CTLX | ')');
|
kbdmip = NULL;
|
||||||
kbdmip = NULL;
|
}
|
||||||
}
|
|
||||||
mlwrite("[Aborted]");
|
mlwrite("[Aborted]");
|
||||||
return (ABORT);
|
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
|
* Display the version. All this does
|
||||||
* is copy the version string into the echo line.
|
* is copy the version string into the echo line.
|
||||||
@@ -480,6 +390,6 @@ int extendedcmd(int f, int n)
|
|||||||
int
|
int
|
||||||
showversion(int f, int n)
|
showversion(int f, int n)
|
||||||
{
|
{
|
||||||
mlwrite("emg 1.8");
|
mlwrite("emg 2.0");
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,25 +9,25 @@
|
|||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
|
|
||||||
extern void mlwrite();
|
extern void mlwrite();
|
||||||
extern void lchange(int flag);
|
extern void lchange(int);
|
||||||
extern int lnewline();
|
extern int lnewline();
|
||||||
extern int linsert(int n, int c);
|
extern int linsert(int, int);
|
||||||
extern int backchar(int f, int n);
|
extern int backchar(int, int);
|
||||||
extern void kdelete();
|
extern void kdelete();
|
||||||
extern int ldelete(int f, int n);
|
extern int ldelete(int, int);
|
||||||
extern int kremove(int k);
|
extern int kremove(int);
|
||||||
|
|
||||||
int setfillcol(int f, int n);
|
int setfillcol(int, int);
|
||||||
int getccol(int bflg);
|
int getccol(int);
|
||||||
int twiddle(int f, int n);
|
int twiddle(int, int);
|
||||||
int quote(int f, int n);
|
int quote(int, int);
|
||||||
int tab(int f, int n);
|
int tab(int, int);
|
||||||
int openline(int f, int n);
|
int openline(int, int);
|
||||||
int newline(int f, int n);
|
int newline(int, int);
|
||||||
int forwdel(int f, int n);
|
int forwdel(int, int);
|
||||||
int backdel(int f, int n);
|
int backdel(int, int);
|
||||||
int killtext(int f, int n);
|
int killtext(int, int);
|
||||||
int yank(int f, int n);
|
int yank(int, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set fill column to n.
|
* Set fill column to n.
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
|
|
||||||
extern void kdelete();
|
extern void kdelete();
|
||||||
extern int ldelete(int f, int n);
|
extern int ldelete(int, int);
|
||||||
extern int kinsert(int c);
|
extern int kinsert(int);
|
||||||
extern void mlwrite();
|
extern void mlwrite();
|
||||||
|
|
||||||
int killregion(int f, int n);
|
int killregion(int, int);
|
||||||
int copyregion(int f, int n);
|
int copyregion(int, int);
|
||||||
int getregion(REGION *rp);
|
int getregion(REGION *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kill the region. Ask "getregion" to figure out the bounds of the region.
|
* Kill the region. Ask "getregion" to figure out the bounds of the region.
|
||||||
|
|||||||
@@ -11,21 +11,21 @@
|
|||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
|
|
||||||
extern void mlwrite();
|
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 void update();
|
||||||
extern int forwchar(int f, int n);
|
extern int forwchar(int, int);
|
||||||
extern int ldelete(int n, int kflag);
|
extern int ldelete(int, int);
|
||||||
extern int linsert(int n, int c);
|
extern int linsert(int, int);
|
||||||
|
|
||||||
int forwsearch(int f, int n);
|
int forwsearch(int, int);
|
||||||
int forwhunt(int f, int n);
|
int forwhunt(int, int);
|
||||||
int backsearch(int f, int n);
|
int backsearch(int, int);
|
||||||
int backhunt(int f, int n);
|
int backhunt(int, int);
|
||||||
int bsearch(int f, int n);
|
int bsearch(int, int);
|
||||||
int eq(int bc, int pc);
|
int eq(int, int);
|
||||||
int readpattern(char *prompt);
|
int readpattern(char *);
|
||||||
int forscan(char *patrn, int leavep);
|
int forscan(char *, int);
|
||||||
void expandp(char *srcstr, char *deststr, int maxlength);
|
void expandp(char *, char *, int);
|
||||||
|
|
||||||
#define PTBEG 1 /* leave the point at the begining on search */
|
#define PTBEG 1 /* leave the point at the begining on search */
|
||||||
#define PTEND 2 /* leave the point at the end on search */
|
#define PTEND 2 /* leave the point at the end on search */
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
/* termios video driver */
|
/* termios video driver */
|
||||||
|
|
||||||
#define termdef 1 /* don't define "term" externally */
|
|
||||||
|
|
||||||
#include <stdio.h> /* puts(3), snprintf(3) */
|
#include <stdio.h> /* puts(3), snprintf(3) */
|
||||||
|
|
||||||
#include "estruct.h"
|
#include "estruct.h"
|
||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
#undef CTRL /* Needs to be done here. */
|
#undef CTRL /* Needs to be done here. */
|
||||||
@@ -22,15 +21,15 @@ extern void ttputc();
|
|||||||
extern void ttflush();
|
extern void ttflush();
|
||||||
extern void ttclose();
|
extern void ttclose();
|
||||||
|
|
||||||
extern void panic();
|
extern void panic(char *);
|
||||||
|
|
||||||
void getwinsize();
|
void getwinsize(void);
|
||||||
void tcapopen();
|
void tcapopen(void);
|
||||||
void tcapmove(int row, int col);
|
void tcapmove(int, int);
|
||||||
void tcapeeol();
|
void tcapeeol(void);
|
||||||
void tcapeeop();
|
void tcapeeop(void);
|
||||||
void tcaprev();
|
void tcaprev(int);
|
||||||
void tcapbeep();
|
void tcapbeep(void);
|
||||||
|
|
||||||
#define MARGIN 8
|
#define MARGIN 8
|
||||||
#define SCRSIZ 64
|
#define SCRSIZ 64
|
||||||
@@ -45,25 +44,27 @@ TERM term = {
|
|||||||
ttflush, tcapmove, tcapeeol, tcapeeop, tcapbeep, tcaprev
|
ttflush, tcapmove, tcapeeol, tcapeeop, tcapbeep, tcaprev
|
||||||
};
|
};
|
||||||
|
|
||||||
void getwinsize()
|
void
|
||||||
|
getwinsize(void)
|
||||||
{
|
{
|
||||||
int cols = COLS;
|
struct winsize ws;
|
||||||
int rows = ROWS;
|
|
||||||
|
|
||||||
/* Too small and we're out */
|
if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
|
||||||
if ((cols < 10) || (rows < 3))
|
term.t_ncol = ws.ws_col;
|
||||||
panic("Too few columns or rows");
|
rows = ws.ws_row;
|
||||||
|
}
|
||||||
|
|
||||||
if (COLS > MAXCOL)
|
/* Too small and we hard code */
|
||||||
cols = MAXCOL;
|
if ((term.t_ncol < 10) || (rows < 3)) {
|
||||||
if (ROWS > MAXROW)
|
term.t_ncol = 80;
|
||||||
rows = MAXROW;
|
rows = 24;
|
||||||
|
}
|
||||||
|
|
||||||
term.t_ncol = cols;
|
|
||||||
term.t_nrow = rows - 1;
|
term.t_nrow = rows - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcapopen()
|
void
|
||||||
|
tcapopen(void)
|
||||||
{
|
{
|
||||||
char tcbuf[1024];
|
char tcbuf[1024];
|
||||||
char *p, *tv_stype;
|
char *p, *tv_stype;
|
||||||
@@ -84,34 +85,39 @@ void tcapopen()
|
|||||||
if (SO != NULL && SE != NULL)
|
if (SO != NULL && SE != NULL)
|
||||||
revexist = TRUE;
|
revexist = TRUE;
|
||||||
if (CL == NULL || CM == NULL)
|
if (CL == NULL || CM == NULL)
|
||||||
panic("Need cl & cm abilities");
|
panic("Need cl & cm abilities");
|
||||||
if (p >= &tcapbuf[TCAPSLEN]) /* XXX */
|
if (p >= &tcapbuf[TCAPSLEN]) /* XXX */
|
||||||
panic("Description too big");
|
panic("Description too big");
|
||||||
ttopen ();
|
ttopen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcaprev(int state)
|
void
|
||||||
|
tcaprev(int state)
|
||||||
{
|
{
|
||||||
if (revexist)
|
if (revexist)
|
||||||
tputs((state ? SO : SE), 1, ttputc);
|
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);
|
tputs(tgoto(CM, col, row), 1, ttputc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcapeeol()
|
void
|
||||||
|
tcapeeol(void)
|
||||||
{
|
{
|
||||||
tputs(CE, 1, ttputc);
|
tputs(CE, 1, ttputc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcapeeop()
|
void
|
||||||
|
tcapeeop(void)
|
||||||
{
|
{
|
||||||
tputs(CL, 1, ttputc);
|
tputs(CL, 1, ttputc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcapbeep()
|
void
|
||||||
|
tcapbeep(void)
|
||||||
{
|
{
|
||||||
ttputc(BEL);
|
ttputc(BEL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
#include "estruct.h"
|
#include "estruct.h"
|
||||||
#include "edef.h"
|
#include "edef.h"
|
||||||
|
|
||||||
extern int backchar(int f, int n);
|
extern int backchar(int, int);
|
||||||
extern int forwchar(int f, int n);
|
extern int forwchar(int, int);
|
||||||
|
|
||||||
int backword(int f, int n);
|
int backword(int, int);
|
||||||
int forwword(int f, int n);
|
int forwword(int, int);
|
||||||
int inword(void);
|
int inword(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -21,14 +21,14 @@ int inword(void);
|
|||||||
* performed by the "backchar" and "forwchar" routines. Error if you try to
|
* performed by the "backchar" and "forwchar" routines. Error if you try to
|
||||||
* move beyond the buffers
|
* move beyond the buffers
|
||||||
*/
|
*/
|
||||||
int backword(int f, int n)
|
int
|
||||||
|
backword(int f, int n)
|
||||||
{
|
{
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return (forwword(f, -n));
|
return (forwword(f, -n));
|
||||||
if (backchar(FALSE, 1) == FALSE)
|
if (backchar(FALSE, 1) == FALSE)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
while (n--)
|
while (n--) {
|
||||||
{
|
|
||||||
while (inword() == FALSE)
|
while (inword() == FALSE)
|
||||||
{
|
{
|
||||||
if (backchar(FALSE, 1) == 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
|
* 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
|
* 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)
|
if (n < 0)
|
||||||
return (backword(f, -n));
|
return (backword(f, -n));
|
||||||
while (n--)
|
while (n--) {
|
||||||
{
|
|
||||||
while (inword() != FALSE)
|
while (inword() != FALSE)
|
||||||
{
|
{
|
||||||
if (forwchar(FALSE, 1) == 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
|
* 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
|
* part of a word. The word character list is hard coded. Should be setable
|
||||||
*/
|
*/
|
||||||
int inword(void)
|
int
|
||||||
|
inword(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
|||||||
@@ -1568,7 +1568,8 @@ int main (argc, argv)
|
|||||||
|
|
||||||
if (! ofilfnd) {
|
if (! ofilfnd) {
|
||||||
unlink ("a.out");
|
unlink ("a.out");
|
||||||
link ("l.out", "a.out");
|
if (link ("l.out", "a.out") < 0)
|
||||||
|
perror("a.out");
|
||||||
ofilename = "a.out";
|
ofilename = "a.out";
|
||||||
}
|
}
|
||||||
delarg = errlev;
|
delarg = errlev;
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ bad1: (void)lseek(rfd, (off_t)r_off, SEEK_SET);
|
|||||||
void symobj()
|
void symobj()
|
||||||
{
|
{
|
||||||
register RLIB *rp;
|
register RLIB *rp;
|
||||||
char hb[sizeof(struct ar_hdr) + 1];
|
char hb[sizeof(struct ar_hdr) + 1 + 64];
|
||||||
long ransize, baseoff;
|
long ransize, baseoff;
|
||||||
|
|
||||||
/* Rewind the archive, leaving the magic number. */
|
/* Rewind the archive, leaving the magic number. */
|
||||||
@@ -385,7 +385,8 @@ int build()
|
|||||||
(void)lseek(tfd, (off_t)0, SEEK_SET);
|
(void)lseek(tfd, (off_t)0, SEEK_SET);
|
||||||
SETCF(tfd, tname, afd, archive, RPAD|WPAD);
|
SETCF(tfd, tname, afd, archive, RPAD|WPAD);
|
||||||
copy_ar(&cf, size);
|
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);
|
(void)close(tfd);
|
||||||
|
|
||||||
/* Set the time. */
|
/* Set the time. */
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ install: smlrc
|
|||||||
clean:
|
clean:
|
||||||
rm -f *.o smlrc smlrc.dis smlrc.elf
|
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 $@
|
${CC} ${CFLAGS} -mips16 smlrc.c -c -o $@
|
||||||
|
|||||||
@@ -546,6 +546,11 @@ void GenFxnProlog(void)
|
|||||||
int i, cnt = CurFxnParamCntMax;
|
int i, cnt = CurFxnParamCntMax;
|
||||||
if (cnt > 4)
|
if (cnt > 4)
|
||||||
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++)
|
for (i = 0; i < cnt; i++)
|
||||||
GenPrintInstr2Operands(MipsInstrSW, 0,
|
GenPrintInstr2Operands(MipsInstrSW, 0,
|
||||||
MipsOpRegA0 + i, 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.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
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);
|
extern int main(int argc, char** argv);
|
||||||
void exit(int);
|
void exit(int);
|
||||||
|
|
||||||
|
#ifdef __SMALLER_C_32__
|
||||||
|
extern void __x87init(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _RETROBSD
|
#ifdef _RETROBSD
|
||||||
void __start__(int argc, char** argv)
|
void __start__(int argc, char** argv)
|
||||||
{
|
{
|
||||||
@@ -75,6 +79,7 @@ void __start__(int argc, char** argv)
|
|||||||
#ifdef _LINUX
|
#ifdef _LINUX
|
||||||
void __start__(int argc, char** argv)
|
void __start__(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
__x87init();
|
||||||
exit(main(argc, argv));
|
exit(main(argc, argv));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -85,6 +90,9 @@ void __start__(void)
|
|||||||
int argc;
|
int argc;
|
||||||
char** argv;
|
char** argv;
|
||||||
__setargs__(&argc, &argv);
|
__setargs__(&argc, &argv);
|
||||||
|
#ifdef __SMALLER_C_32__
|
||||||
|
__x87init();
|
||||||
|
#endif
|
||||||
exit(main(argc, argv));
|
exit(main(argc, argv));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -371,6 +379,22 @@ void* memset(void* s, int c, unsigned n)
|
|||||||
return s;
|
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 fputc(int c, FILE* stream);
|
||||||
int putchar(int c);
|
int putchar(int c);
|
||||||
|
|
||||||
@@ -1548,4 +1572,187 @@ int fsetpos(FILE* stream, fpos_t* pos)
|
|||||||
|
|
||||||
return 0;
|
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__*/
|
#endif /*__APPLE__*/
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/termios.h>
|
#include <termios.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ strip(name)
|
|||||||
head.a_reldata = 0;
|
head.a_reldata = 0;
|
||||||
head.a_syms = 0;
|
head.a_syms = 0;
|
||||||
(void) lseek(f, (off_t)0, SEEK_SET);
|
(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:
|
out:
|
||||||
close(f);
|
close(f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ OPTON = -O2 -fomit-frame-pointer -fforce-addr -ffast-math -Wall
|
|||||||
#CFLAGS = -DTIME -std1 -verbose -w0
|
#CFLAGS = -DTIME -std1 -verbose -w0
|
||||||
|
|
||||||
## generic gcc CFLAGS. -DTIME must be included
|
## generic gcc CFLAGS. -DTIME must be included
|
||||||
CFLAGS = -DTIME -Wall -pedantic -ansi
|
#CFLAGS = -DTIME -Wall -pedantic -ansi
|
||||||
|
|
||||||
# local directories
|
# local directories
|
||||||
PROGDIR = ./pgms
|
PROGDIR = ./pgms
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ char *vi_Version =
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
//#include <termios.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@@ -81,12 +80,17 @@ char *vi_Version =
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
//#include <err.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "lib/last_char_is.c"
|
#include "lib/last_char_is.c"
|
||||||
#include "lib/strlcat.c"
|
#if defined(linux) || defined(__APPLE__)
|
||||||
#include "lib/strlcpy.c"
|
# include <termios.h>
|
||||||
|
# include <err.h>
|
||||||
|
#else
|
||||||
|
# include "lib/strlcat.c"
|
||||||
|
# include "lib/strlcpy.c"
|
||||||
|
# define termios sgttyb
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
@@ -96,7 +100,6 @@ char *vi_Version =
|
|||||||
#endif /* TRUE */
|
#endif /* TRUE */
|
||||||
#define MAX_SCR_COLS BUFSIZ
|
#define MAX_SCR_COLS BUFSIZ
|
||||||
#define BUFSIZ_STATBUF 200
|
#define BUFSIZ_STATBUF 200
|
||||||
#define termios sgttyb
|
|
||||||
|
|
||||||
// Misc. non-Ascii keys that report an escape sequence
|
// Misc. non-Ascii keys that report an escape sequence
|
||||||
#define VI_K_UP 128 // cursor key Up
|
#define VI_K_UP 128 // cursor key Up
|
||||||
@@ -1789,7 +1792,8 @@ static void colon(Byte * buf)
|
|||||||
while (isblnk(*buf))
|
while (isblnk(*buf))
|
||||||
buf++;
|
buf++;
|
||||||
/* FIXED strcpy((char *) args, (char *) 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, '!');
|
buf1 = (Byte *)last_char_is((char *)cmd, '!');
|
||||||
if (buf1) {
|
if (buf1) {
|
||||||
useforce = TRUE;
|
useforce = TRUE;
|
||||||
@@ -3183,7 +3187,7 @@ static int isblnk(Byte c) // is the char a blank or tab
|
|||||||
//----- Set terminal attributes --------------------------------
|
//----- Set terminal attributes --------------------------------
|
||||||
static void rawmode(void)
|
static void rawmode(void)
|
||||||
{
|
{
|
||||||
#if 0
|
#ifdef TCSANOW
|
||||||
tcgetattr(0, &term_orig);
|
tcgetattr(0, &term_orig);
|
||||||
term_vi = term_orig;
|
term_vi = term_orig;
|
||||||
term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG ON- allow intr's
|
term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG ON- allow intr's
|
||||||
@@ -3208,7 +3212,7 @@ static void rawmode(void)
|
|||||||
|
|
||||||
static void cookmode(void)
|
static void cookmode(void)
|
||||||
{
|
{
|
||||||
#if 0
|
#ifdef TCSANOW
|
||||||
tcsetattr(0, TCSANOW, &term_orig);
|
tcsetattr(0, TCSANOW, &term_orig);
|
||||||
#else
|
#else
|
||||||
ioctl(0, TIOCSETP, &term_orig);
|
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
|
# Makefile: makefile for yacc
|
||||||
#
|
# Copyright 2012 Majenko Technolohies
|
||||||
DESTDIR=
|
# (matt@majenko.co.uk
|
||||||
SEPFLAG= -i
|
# Last Modified: 29/01/2012
|
||||||
CFLAGS=-O
|
#==========================================
|
||||||
SRCS = Makefile dextern files yaccpar \
|
|
||||||
y1.c y2.c y3.c y4.c \
|
|
||||||
yaccdiffs yaccnews
|
|
||||||
|
|
||||||
all: yacc
|
TOPSRC = $(shell cd ../../..; pwd)
|
||||||
|
include $(TOPSRC)/target.mk
|
||||||
|
|
||||||
yacc: y1.o y2.o y3.o y4.o
|
OBJS = y1.o y2.o y3.o y4.o
|
||||||
$(CC) ${SEPFLAG} -o yacc y?.o
|
SRCS = y1.c y2.c y3.c y4.c
|
||||||
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
|
|
||||||
|
|
||||||
srcs: $(SRCS)
|
all: yacc
|
||||||
$(SRCS):
|
|
||||||
sccs get $@
|
yacc: ${OBJS}
|
||||||
|
${CC} ${LDFLAGS} -o yacc.elf ${OBJS} ${LIBS}
|
||||||
|
${OBJDUMP} -S yacc.elf > yacc.dis
|
||||||
|
${SIZE} yacc.elf
|
||||||
|
${ELF2AOUT} yacc.elf $@
|
||||||
|
|
||||||
|
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
|
# ifdef MEDIUM
|
||||||
# define ACTSIZE 4000
|
# define ACTSIZE 4000
|
||||||
# define MEMSIZE 5200
|
# define MEMSIZE 5200
|
||||||
# define NSTATES 600
|
# define NSTATES 750
|
||||||
# define NTERMS 127
|
# define NTERMS 127
|
||||||
# define NPROD 400
|
# define NPROD 400
|
||||||
# define NNONTERM 200
|
# define NNONTERM 200
|
||||||
@@ -43,6 +43,19 @@
|
|||||||
# define WSETSIZE 250
|
# define WSETSIZE 250
|
||||||
# endif
|
# 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 NAMESIZE 50
|
||||||
# define NTYPES 63
|
# define NTYPES 63
|
||||||
|
|
||||||
|
|||||||
@@ -17,4 +17,5 @@
|
|||||||
|
|
||||||
/* basic size of the Yacc implementation */
|
/* basic size of the Yacc implementation */
|
||||||
/* # define HUGE */
|
/* # 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
|
#endif
|
||||||
|
|
||||||
# include "dextern"
|
# include "dextern"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* variables used locally */
|
/* variables used locally */
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,19 @@
|
|||||||
*/
|
*/
|
||||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
||||||
"elf32-littlemips")
|
"elf32-littlemips")
|
||||||
OUTPUT_ARCH(mips)
|
OUTPUT_ARCH(pic32mx)
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
/* Required by Microchip C32 linker */
|
/* Required by Microchip C32 linker */
|
||||||
/*MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x80000
|
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 512K
|
||||||
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
|
exception_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x1000
|
||||||
exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
|
kseg0_boot_mem (rx) : ORIGIN = 0x9FC00000, LENGTH = 12K-16
|
||||||
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490
|
kseg1_boot_mem (rx) : ORIGIN = 0xBFC00000, LENGTH = 0x490
|
||||||
kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x20000
|
kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x20000
|
||||||
}*/
|
}
|
||||||
|
_min_heap_size = 0;
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
|||||||
1
src/games/.gitignore
vendored
1
src/games/.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
aclock
|
||||||
arithmetic
|
arithmetic
|
||||||
banner
|
banner
|
||||||
bcd
|
bcd
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ SUBDIR = adventure atc backgammon battlestar boggle btlgammon \
|
|||||||
# C programs that live in the current directory and do not need
|
# C programs that live in the current directory and do not need
|
||||||
# explicit make lines.
|
# explicit make lines.
|
||||||
#
|
#
|
||||||
STD = banner arithmetic bcd cfscores factor fish morse \
|
STD = banner aclock arithmetic bcd cfscores factor fish morse \
|
||||||
number ppt wump
|
number ppt wump
|
||||||
|
|
||||||
# C programs that live in the current directory and need explicit make lines.
|
# 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)/target.mk
|
||||||
#include $(TOPSRC)/cross.mk
|
#include $(TOPSRC)/cross.mk
|
||||||
|
|
||||||
CFLAGS = -Os -g -Werror -Wall
|
CFLAGS += -Os -g -Werror -Wall
|
||||||
CFLAGS += -DBSD -DDEST=\"/games/lib/atc/\"
|
CFLAGS += -DBSD -DDEST=\"/games/lib/atc/\"
|
||||||
#CFLAGS += -DSYSV -DDEST=\"games/\"
|
#CFLAGS += -DSYSV -DDEST=\"games/\"
|
||||||
YFLAGS = -d
|
YFLAGS = -d
|
||||||
|
|||||||
@@ -4,16 +4,27 @@
|
|||||||
* All rights reserved. The Berkeley software License Agreement
|
* All rights reserved. The Berkeley software License Agreement
|
||||||
* specifies the terms and conditions for redistribution.
|
* specifies the terms and conditions for redistribution.
|
||||||
*/
|
*/
|
||||||
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <ctype.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
|
double
|
||||||
atof(p)
|
atof(p)
|
||||||
register char *p;
|
register char *p;
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
double fl, flexp, exp5;
|
double fl, flexp, exp5;
|
||||||
double big = 72057594037927936.; /*2^56*/
|
double big = BIG;
|
||||||
int nd;
|
int nd;
|
||||||
register int eexp, exp, neg, negexp, bexp;
|
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;
|
fl = 0;
|
||||||
exp = 0;
|
exp = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
double
|
double
|
||||||
@@ -5,10 +6,11 @@ ldexp(fr, exp)
|
|||||||
double fr;
|
double fr;
|
||||||
int exp;
|
int exp;
|
||||||
{
|
{
|
||||||
double huge = 1.701411834604692293e38;
|
|
||||||
int neg;
|
int neg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (fr == 0)
|
||||||
|
return 0;
|
||||||
neg = 0;
|
neg = 0;
|
||||||
if (fr < 0) {
|
if (fr < 0) {
|
||||||
fr = -fr;
|
fr = -fr;
|
||||||
@@ -20,13 +22,13 @@ ldexp(fr, exp)
|
|||||||
i = i-1;
|
i = i-1;
|
||||||
}
|
}
|
||||||
exp = exp+i;
|
exp = exp+i;
|
||||||
if (exp > 127) {
|
if (exp >= DBL_MAX_EXP) {
|
||||||
if (neg)
|
if (neg)
|
||||||
return(-huge);
|
return(-HUGE_VAL);
|
||||||
else
|
else
|
||||||
return(huge);
|
return(HUGE_VAL);
|
||||||
}
|
}
|
||||||
if (exp < -127)
|
if (exp < DBL_MIN_EXP - 2)
|
||||||
return(0);
|
return(0);
|
||||||
while (exp > 30) {
|
while (exp > 30) {
|
||||||
fr = fr*(1L<<30);
|
fr = fr*(1L<<30);
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ include $(TOPSRC)/target.mk
|
|||||||
CFLAGS += ${DEFS}
|
CFLAGS += ${DEFS}
|
||||||
|
|
||||||
OBJS = addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \
|
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}
|
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
|
#define SINGLE_PRECISION
|
||||||
#include "fp_lib.h"
|
#include "fp_lib.h"
|
||||||
|
|
||||||
//#include "int_lib.h"
|
|
||||||
|
|
||||||
fp_t
|
fp_t
|
||||||
__floatsisf(int a)
|
__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 <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
/* Max number conversion buffer length: a long in base 2, plus NUL byte. */
|
/* Max number conversion buffer length. */
|
||||||
#define MAXNBUF (sizeof(long) * 8 + 1)
|
#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,
|
static unsigned char *ksprintn (unsigned char *buf, unsigned long v, unsigned char base,
|
||||||
int width, unsigned char *lp);
|
int width, unsigned char *lp);
|
||||||
@@ -169,21 +171,11 @@ reswitch: switch (c = *fmt++) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
s = va_arg (ap, const unsigned char*);
|
lflag=1;
|
||||||
if (! width)
|
/* FALLTHROUGH */
|
||||||
width = 16;
|
|
||||||
if (sharpflag)
|
|
||||||
padding = ':';
|
|
||||||
while (width--) {
|
|
||||||
c = *s++;
|
|
||||||
PUTC (mkhex (c >> 4));
|
|
||||||
PUTC (mkhex (c));
|
|
||||||
if (width)
|
|
||||||
PUTC (padding);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
|
case 'i':
|
||||||
ul = lflag ? va_arg (ap, long) : va_arg (ap, int);
|
ul = lflag ? va_arg (ap, long) : va_arg (ap, int);
|
||||||
if (! sign) sign = 1;
|
if (! sign) sign = 1;
|
||||||
base = 10;
|
base = 10;
|
||||||
@@ -209,7 +201,7 @@ reswitch: switch (c = *fmt++) {
|
|||||||
sharpflag = (width == 0);
|
sharpflag = (width == 0);
|
||||||
goto nosign;
|
goto nosign;
|
||||||
|
|
||||||
case 'n':
|
case 'n': /* TBD!!! fix this non-standard %n */
|
||||||
ul = lflag ? va_arg (ap, unsigned long) :
|
ul = lflag ? va_arg (ap, unsigned long) :
|
||||||
sign ? (unsigned long) va_arg (ap, int) :
|
sign ? (unsigned long) va_arg (ap, int) :
|
||||||
va_arg (ap, unsigned int);
|
va_arg (ap, unsigned int);
|
||||||
@@ -292,7 +284,7 @@ cnt_unknown: if (ladjust)
|
|||||||
goto number;
|
goto number;
|
||||||
|
|
||||||
nosign: sign = 0;
|
nosign: sign = 0;
|
||||||
number: if (sign && ((long) ul != 0L)) {
|
number: if (sign) {
|
||||||
if ((long) ul < 0L) {
|
if ((long) ul < 0L) {
|
||||||
neg = '-';
|
neg = '-';
|
||||||
ul = -(long) ul;
|
ul = -(long) ul;
|
||||||
@@ -403,7 +395,7 @@ number: if (sign && ((long) ul != 0L)) {
|
|||||||
nbuf [size + 1] = 0;
|
nbuf [size + 1] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (neg)
|
if (neg || sign)
|
||||||
size++;
|
size++;
|
||||||
if (! ladjust && width && padding == ' ' &&
|
if (! ladjust && width && padding == ' ' &&
|
||||||
(width -= size) > 0)
|
(width -= size) > 0)
|
||||||
@@ -411,8 +403,11 @@ number: if (sign && ((long) ul != 0L)) {
|
|||||||
PUTC (' ');
|
PUTC (' ');
|
||||||
} while (--width > 0);
|
} while (--width > 0);
|
||||||
|
|
||||||
if (neg)
|
if (neg) {
|
||||||
PUTC ('-');
|
PUTC ('-');
|
||||||
|
} else if (sign) {
|
||||||
|
PUTC ('+');
|
||||||
|
}
|
||||||
|
|
||||||
if (! ladjust && width && (width -= size) > 0)
|
if (! ladjust && width && (width -= size) > 0)
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ CFLAGS += -O -Wall -Werror
|
|||||||
MAN = gpanel.0
|
MAN = gpanel.0
|
||||||
MANSRC = gpanel.3
|
MANSRC = gpanel.3
|
||||||
|
|
||||||
OBJS = open.o clear.o pixel.o line.o rect.o fill.o circle.o \
|
OBJS = open.o clear.o pixel.o line.o rect.o fill.o fill_triangle.o \
|
||||||
image.o char.o text.o text_width.o
|
circle.o image.o char.o text.o text_width.o
|
||||||
|
|
||||||
all: ../libgpanel.a $(MAN)
|
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)
|
* The coefficients are #1069 from Hart and Cheney. (22.35D)
|
||||||
*/
|
*/
|
||||||
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ static double q1 = .3277251518082914423057964422e6;
|
|||||||
static double q2 = .1749287689093076403844945335e4;
|
static double q2 = .1749287689093076403844945335e4;
|
||||||
static double log2e = 1.4426950408889634073599247;
|
static double log2e = 1.4426950408889634073599247;
|
||||||
static double sqrt2 = 1.4142135623730950488016887;
|
static double sqrt2 = 1.4142135623730950488016887;
|
||||||
static double maxf = 10000;
|
static double maxf = DBL_MAX_10_EXP * 2.5/*>ln(10)*/;
|
||||||
|
|
||||||
double
|
double
|
||||||
exp(arg)
|
exp(arg)
|
||||||
@@ -32,7 +33,7 @@ double arg;
|
|||||||
return(0.);
|
return(0.);
|
||||||
if(arg > maxf) {
|
if(arg > maxf) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return(HUGE);
|
return(HUGE_VAL);
|
||||||
}
|
}
|
||||||
arg *= log2e;
|
arg *= log2e;
|
||||||
ent = floor(arg);
|
ent = floor(arg);
|
||||||
|
|||||||
295
src/libm/fmod.c
295
src/libm/fmod.c
@@ -1,111 +1,268 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.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,};
|
static const double one = 1.0, Zero[] = {0.0, -0.0,};
|
||||||
|
|
||||||
double fmod(double x, double y)
|
double fmod(double x, double y)
|
||||||
{
|
{
|
||||||
int32_t n=0,hx=0,hy=0,hz=0,ix=0,iy=0,sx=0,i=0;
|
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);
|
if (sizeof(float) == sizeof(double)) {
|
||||||
EXTRACT_WORDS(hy,ly,y);
|
/*
|
||||||
sx = hx&0x80000000; /* sign of x */
|
* Double is 32-bit.
|
||||||
hx ^=sx; /* |x| */
|
*/
|
||||||
hy &= 0x7fffffff; /* |y| */
|
UNPACK_FLOAT(hx,x);
|
||||||
|
UNPACK_FLOAT(hy,y);
|
||||||
|
sx = hx & 0x80000000; /* sign of x */
|
||||||
|
hx ^= sx; /* |x| */
|
||||||
|
hy &= 0x7fffffff; /* |y| */
|
||||||
|
|
||||||
/* purge off exception values */
|
/* purge off exception values */
|
||||||
if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
|
if (hy == 0 || hx >= 0x7f800000 || /* y=0, or x not finite */
|
||||||
((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
|
hy > 0x7f800000) /* or y is NaN */
|
||||||
return (x*y)/(x*y);
|
return (x*y) / (x*y);
|
||||||
if(hx<=hy) {
|
if (hx < hy)
|
||||||
if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
|
return x; /* |x| < |y| return x */
|
||||||
if(lx==ly)
|
if (hx == hy)
|
||||||
return Zero[(uint32_t)sx>>31]; /* |x|=|y| return x*0*/
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* determine ix = ilogb(x) */
|
/* fix point fmod */
|
||||||
if(hx<0x00100000) { /* subnormal x */
|
n = ix - iy;
|
||||||
if(hx==0) {
|
while (n--) {
|
||||||
for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
|
hz = hx - hy;
|
||||||
|
if (hz < 0) {
|
||||||
|
hx = hx + hx;
|
||||||
} else {
|
} else {
|
||||||
for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
|
if (hz == 0) /* return sign(x)*0 */
|
||||||
|
return Zero[(uint32_t)sx >> 31];
|
||||||
|
hx = hz + hz;
|
||||||
}
|
}
|
||||||
} else ix = (hx>>20)-1023;
|
}
|
||||||
|
hz = hx - hy;
|
||||||
|
if (hz >= 0) {
|
||||||
|
hx = hz;
|
||||||
|
}
|
||||||
|
|
||||||
/* determine iy = ilogb(y) */
|
/* convert back to floating value and restore the sign */
|
||||||
if(hy<0x00100000) { /* subnormal y */
|
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 (lx == ly)
|
||||||
|
return Zero[(uint32_t)sx >> 31]; /* |x| = |y| return x*0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine ix = ilogb(x) */
|
||||||
|
if (hx < 0x00100000) { /* subnormal x */
|
||||||
|
if (hx == 0) {
|
||||||
|
for (ix = -1043, i=lx; i>0; i<<=1)
|
||||||
|
ix -= 1;
|
||||||
|
} else {
|
||||||
|
for (ix = -1022, i=hx<<11; i>0; i<<=1)
|
||||||
|
ix -= 1;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
ix = (hx >> 20) - 1023;
|
||||||
|
|
||||||
|
/* determine iy = ilogb(y) */
|
||||||
|
if (hy < 0x00100000) { /* subnormal y */
|
||||||
if(hy==0) {
|
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 {
|
} 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 */
|
/* set up {hx,lx}, {hy,ly} and align y to x */
|
||||||
if(ix >= -1022)
|
if (ix >= -1022)
|
||||||
hx = 0x00100000|(0x000fffff&hx);
|
hx = 0x00100000 | (0x000fffff & hx);
|
||||||
else { /* subnormal x, shift x to normal */
|
else { /* subnormal x, shift x to normal */
|
||||||
n = -1022-ix;
|
n = -1022 - ix;
|
||||||
if(n<=31) {
|
if (n <= 31) {
|
||||||
hx = (hx<<n)|(lx>>(32-n));
|
hx = (hx << n) | (lx >> (32 - n));
|
||||||
lx <<= n;
|
lx <<= n;
|
||||||
} else {
|
} else {
|
||||||
hx = lx<<(n-32);
|
hx = lx << (n - 32);
|
||||||
lx = 0;
|
lx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(iy >= -1022)
|
if (iy >= -1022)
|
||||||
hy = 0x00100000|(0x000fffff&hy);
|
hy = 0x00100000 | (0x000fffff & hy);
|
||||||
else { /* subnormal y, shift y to normal */
|
else { /* subnormal y, shift y to normal */
|
||||||
n = -1022-iy;
|
n = -1022 - iy;
|
||||||
if(n<=31) {
|
if (n <= 31) {
|
||||||
hy = (hy<<n)|(ly>>(32-n));
|
hy = (hy << n) | (ly >> (32 - n));
|
||||||
ly <<= n;
|
ly <<= n;
|
||||||
} else {
|
} else {
|
||||||
hy = ly<<(n-32);
|
hy = ly << (n - 32);
|
||||||
ly = 0;
|
ly = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fix point fmod */
|
/* fix point fmod */
|
||||||
n = ix - iy;
|
n = ix - iy;
|
||||||
while(n--) {
|
while (n--) {
|
||||||
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
|
hz = hx - hy;
|
||||||
if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
|
lz = lx - ly;
|
||||||
else {
|
if (lx < ly)
|
||||||
if((hz|lz)==0) /* return sign(x)*0 */
|
hz -= 1;
|
||||||
return Zero[(uint32_t)sx>>31];
|
|
||||||
hx = hz+hz+(lz>>31); lx = lz+lz;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
|
hz = hx - hy;
|
||||||
if(hz>=0) {hx=hz;lx=lz;}
|
lz = lx - ly;
|
||||||
|
if (lx < ly)
|
||||||
|
hz -= 1;
|
||||||
|
if (hz >= 0) {
|
||||||
|
hx = hz;
|
||||||
|
lx = lz;
|
||||||
|
}
|
||||||
|
|
||||||
/* convert back to floating value and restore the sign */
|
/* convert back to floating value and restore the sign */
|
||||||
if((hx|lx)==0) /* return sign(x)*0 */
|
if ((hx | lx) == 0) /* return sign(x)*0 */
|
||||||
return Zero[(uint32_t)sx>>31];
|
return Zero[(uint32_t)sx >> 31];
|
||||||
while(hx<0x00100000) { /* normalize x */
|
while (hx < 0x00100000) { /* normalize x */
|
||||||
hx = hx+hx+(lx>>31); lx = lx+lx;
|
hx = hx + hx + (lx >> 31);
|
||||||
|
lx = lx + lx;
|
||||||
iy -= 1;
|
iy -= 1;
|
||||||
}
|
}
|
||||||
if(iy>= -1022) { /* normalize output */
|
if (iy >= -1022) { /* normalize output */
|
||||||
hx = ((hx-0x00100000)|((iy+1023)<<20));
|
hx = (hx - 0x00100000) | ((iy + 1023) << 20);
|
||||||
INSERT_WORDS(x,hx|sx,lx);
|
PACK_DOUBLE(x, hx | sx, lx);
|
||||||
} else { /* subnormal output */
|
} else { /* subnormal output */
|
||||||
n = -1022 - iy;
|
n = -1022 - iy;
|
||||||
if(n<=20) {
|
if (n <= 20) {
|
||||||
lx = (lx>>n)|((uint32_t)hx<<(32-n));
|
lx = (lx >> n) | ((uint32_t)hx << (32 - n));
|
||||||
hx >>= n;
|
hx >>= n;
|
||||||
} else if (n<=31) {
|
} else if (n <= 31) {
|
||||||
lx = (hx<<(32-n))|(lx>>n); hx = sx;
|
lx = (hx << (32 - n)) | (lx >> n);
|
||||||
|
hx = sx;
|
||||||
} else {
|
} 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 */
|
x *= one; /* create necessary signal */
|
||||||
}
|
}
|
||||||
return x; /* exact output */
|
}
|
||||||
|
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;
|
errno = 0;
|
||||||
if(arg <= 0.){
|
if(arg <= 0.){
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return(-HUGE);
|
return(-HUGE_VAL);
|
||||||
}
|
}
|
||||||
if(arg > 8.){
|
if(arg > 8.){
|
||||||
asympt(arg);
|
asympt(arg);
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ y1(arg)
|
|||||||
x = arg;
|
x = arg;
|
||||||
if(x <= 0.){
|
if(x <= 0.){
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return(-HUGE);
|
return(-HUGE_VAL);
|
||||||
}
|
}
|
||||||
if(x > 8.){
|
if(x > 8.){
|
||||||
asympt(x);
|
asympt(x);
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ yn(n,x) int n; double x;{
|
|||||||
|
|
||||||
if (x <= 0) {
|
if (x <= 0) {
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return(-HUGE);
|
return(-HUGE_VAL);
|
||||||
}
|
}
|
||||||
sign = 1;
|
sign = 1;
|
||||||
if(n<0){
|
if(n<0){
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ double arg;
|
|||||||
|
|
||||||
if(arg <= 0.) {
|
if(arg <= 0.) {
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return(-HUGE);
|
return(-HUGE_VAL);
|
||||||
}
|
}
|
||||||
x = frexp(arg,&exp);
|
x = frexp(arg,&exp);
|
||||||
while(x<0.5) {
|
while(x<0.5) {
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ tan(arg)
|
|||||||
if(temp == 0.) {
|
if(temp == 0.) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (sign>0)
|
if (sign>0)
|
||||||
return(HUGE);
|
return(HUGE_VAL);
|
||||||
return(-HUGE);
|
return(-HUGE_VAL);
|
||||||
}
|
}
|
||||||
temp = 1./temp;
|
temp = 1./temp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#endif /* !MAL */
|
#endif /* !MAL */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
imalloc(n)
|
imalloc(int n)
|
||||||
{
|
{
|
||||||
#ifdef MAL
|
#ifdef MAL
|
||||||
register char * result;
|
register char * result;
|
||||||
@@ -33,7 +33,7 @@ imalloc(n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
icalloc(nelem, elsize)
|
icalloc(int nelem, int elsize)
|
||||||
{
|
{
|
||||||
if (nelem == 0 || elsize == 0)
|
if (nelem == 0 || elsize == 0)
|
||||||
nelem = elsize = 1;
|
nelem = elsize = 1;
|
||||||
@@ -41,8 +41,7 @@ icalloc(nelem, elsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
irealloc(pointer, size)
|
irealloc(char *pointer, int size)
|
||||||
char * pointer;
|
|
||||||
{
|
{
|
||||||
if (NULLMAL(pointer))
|
if (NULLMAL(pointer))
|
||||||
return imalloc(size);
|
return imalloc(size);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ static void
|
|||||||
show(zone, t, v)
|
show(zone, t, v)
|
||||||
char * zone;
|
char * zone;
|
||||||
time_t t;
|
time_t t;
|
||||||
|
int v;
|
||||||
{
|
{
|
||||||
struct tm * tmp;
|
struct tm * tmp;
|
||||||
|
|
||||||
|
|||||||
@@ -309,6 +309,8 @@ static void
|
|||||||
eats(name, num, rname, rnum)
|
eats(name, num, rname, rnum)
|
||||||
char * name;
|
char * name;
|
||||||
char * rname;
|
char * rname;
|
||||||
|
int num;
|
||||||
|
int rnum;
|
||||||
{
|
{
|
||||||
filename = name;
|
filename = name;
|
||||||
linenum = num;
|
linenum = num;
|
||||||
@@ -319,6 +321,7 @@ char * rname;
|
|||||||
static void
|
static void
|
||||||
eat(name, num)
|
eat(name, num)
|
||||||
char * name;
|
char * name;
|
||||||
|
int num;
|
||||||
{
|
{
|
||||||
eats(name, num, (char *) NULL, -1);
|
eats(name, num, (char *) NULL, -1);
|
||||||
}
|
}
|
||||||
@@ -653,6 +656,7 @@ static long
|
|||||||
gethms(string, errstring, signable)
|
gethms(string, errstring, signable)
|
||||||
char * string;
|
char * string;
|
||||||
char * errstring;
|
char * errstring;
|
||||||
|
int signable;
|
||||||
{
|
{
|
||||||
int hh, mm, ss, sign;
|
int hh, mm, ss, sign;
|
||||||
|
|
||||||
@@ -687,6 +691,7 @@ char * errstring;
|
|||||||
static void
|
static void
|
||||||
inrule(fields, nfields)
|
inrule(fields, nfields)
|
||||||
register char ** fields;
|
register char ** fields;
|
||||||
|
int nfields;
|
||||||
{
|
{
|
||||||
struct rule r;
|
struct rule r;
|
||||||
|
|
||||||
@@ -713,6 +718,7 @@ register char ** fields;
|
|||||||
static int
|
static int
|
||||||
inzone(fields, nfields)
|
inzone(fields, nfields)
|
||||||
register char ** fields;
|
register char ** fields;
|
||||||
|
int nfields;
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
char buf[132];
|
char buf[132];
|
||||||
@@ -743,8 +749,9 @@ register char ** fields;
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
inzcont(fields, nfields)
|
inzcont(fields, nfields)
|
||||||
register char ** fields;
|
register char ** fields;
|
||||||
|
int nfields;
|
||||||
{
|
{
|
||||||
if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
|
if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
|
||||||
error("wrong number of fields on Zone continuation line");
|
error("wrong number of fields on Zone continuation line");
|
||||||
@@ -756,6 +763,8 @@ register char ** fields;
|
|||||||
static int
|
static int
|
||||||
inzsub(fields, nfields, iscont)
|
inzsub(fields, nfields, iscont)
|
||||||
register char ** fields;
|
register char ** fields;
|
||||||
|
int nfields;
|
||||||
|
int iscont;
|
||||||
{
|
{
|
||||||
register char * cp;
|
register char * cp;
|
||||||
struct zone z;
|
struct zone z;
|
||||||
@@ -826,6 +835,7 @@ error("Zone continuation line end time is not after end time of previous line");
|
|||||||
static void
|
static void
|
||||||
inlink(fields, nfields)
|
inlink(fields, nfields)
|
||||||
register char ** fields;
|
register char ** fields;
|
||||||
|
int nfields;
|
||||||
{
|
{
|
||||||
struct link l;
|
struct link l;
|
||||||
|
|
||||||
@@ -1055,6 +1065,7 @@ char * name;
|
|||||||
static void
|
static void
|
||||||
outzone(zpfirst, zonecount)
|
outzone(zpfirst, zonecount)
|
||||||
struct zone * zpfirst;
|
struct zone * zpfirst;
|
||||||
|
int zonecount;
|
||||||
{
|
{
|
||||||
register struct zone * zp;
|
register struct zone * zp;
|
||||||
register struct rule * rp;
|
register struct rule * rp;
|
||||||
@@ -1200,6 +1211,7 @@ addtt(starttime, addtype(startoff, startbuf, startisdst));
|
|||||||
static void
|
static void
|
||||||
addtt(starttime, type)
|
addtt(starttime, type)
|
||||||
time_t starttime;
|
time_t starttime;
|
||||||
|
int type;
|
||||||
{
|
{
|
||||||
if (timecnt != 0 && type == types[timecnt - 1])
|
if (timecnt != 0 && type == types[timecnt - 1])
|
||||||
return; /* easy enough! */
|
return; /* easy enough! */
|
||||||
@@ -1216,6 +1228,7 @@ static int
|
|||||||
addtype(gmtoff, abbr, isdst)
|
addtype(gmtoff, abbr, isdst)
|
||||||
long gmtoff;
|
long gmtoff;
|
||||||
char * abbr;
|
char * abbr;
|
||||||
|
int isdst;
|
||||||
{
|
{
|
||||||
register int i, j;
|
register int i, j;
|
||||||
|
|
||||||
@@ -1251,6 +1264,7 @@ char * abbr;
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
yearistype(year, type)
|
yearistype(year, type)
|
||||||
|
int year;
|
||||||
char * type;
|
char * type;
|
||||||
{
|
{
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
@@ -1276,7 +1290,7 @@ char * type;
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lowerit(a)
|
lowerit(int a)
|
||||||
{
|
{
|
||||||
return (isascii(a) && isupper(a)) ? tolower(a) : a;
|
return (isascii(a) && isupper(a)) ? tolower(a) : a;
|
||||||
}
|
}
|
||||||
@@ -1538,7 +1552,7 @@ char * name;
|
|||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
eitol(i)
|
eitol(int i)
|
||||||
{
|
{
|
||||||
long l;
|
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_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_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(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_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_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);
|
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.
|
* Kernel driver routines.
|
||||||
*/
|
*/
|
||||||
|
struct uio;
|
||||||
extern int gpanel_open(dev_t dev, int flag, int mode);
|
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_close(dev_t dev, int flag, int mode);
|
||||||
extern int gpanel_read(dev_t dev, struct uio *uio, int flag);
|
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_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_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 /* KERNEL */
|
||||||
|
|
||||||
#endif /* _GPANEL_H */
|
#endif /* _GPANEL_H */
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
||||||
"elf32-littlemips")
|
"elf32-littlemips")
|
||||||
OUTPUT_ARCH(mips)
|
OUTPUT_ARCH(pic32mx)
|
||||||
ENTRY(_reset_vector_)
|
ENTRY(_reset_vector_)
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ options "EXEC_AOUT" # Run a.out binaries
|
|||||||
options "EXEC_ELF" # Run ELF binaries
|
options "EXEC_ELF" # Run ELF binaries
|
||||||
options "EXEC_SCRIPT" # Run shell scripts
|
options "EXEC_SCRIPT" # Run shell scripts
|
||||||
options "UCB_METER" # Collect kernel statistics
|
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 "NBUF=10" # Number of i/o buffers, default 10
|
||||||
options "NFILE=24" # Number of files, default 24
|
options "NFILE=24" # Number of files, default 24
|
||||||
options "NINODE=24" # Number of i-nodes, 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
|
options "PICGA_BUS=SPI1CON" # TODO: delete this option
|
||||||
signal "PICGA_CS" pin RA4 # TODO: delete
|
signal "PICGA_CS" pin RA4 # TODO: delete
|
||||||
|
|
||||||
# ST7781 TFT display driver
|
# TFT display driver with 8-bit parallel interface.
|
||||||
device swtft
|
# Supported controllers: ST7781, ILI9341, NT35702
|
||||||
|
device gpanel
|
||||||
signal "LCD_RST" pin RB10
|
signal "LCD_RST" pin RB10
|
||||||
signal "LCD_CS" pin RB0
|
signal "LCD_CS" pin RB0
|
||||||
signal "LCD_RD" pin RB2
|
signal "LCD_RD" pin RB2
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
||||||
"elf32-littlemips")
|
"elf32-littlemips")
|
||||||
OUTPUT_ARCH(mips)
|
OUTPUT_ARCH(pic32mx)
|
||||||
ENTRY(_reset_vector_)
|
ENTRY(_reset_vector_)
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -317,7 +317,8 @@ const struct cdevsw cdevsw[] = {
|
|||||||
#if GPANEL_MAJOR != 16
|
#if GPANEL_MAJOR != 16
|
||||||
# error Wrong GPANEL_MAJOR value!
|
# error Wrong GPANEL_MAJOR value!
|
||||||
#endif
|
#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_open, gpanel_close, gpanel_read, gpanel_write,
|
||||||
gpanel_ioctl, nulldev, 0, seltrue,
|
gpanel_ioctl, nulldev, 0, seltrue,
|
||||||
nostrategy, 0, 0,
|
nostrategy, 0, 0,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ ldscript "maximite/bootloader.ld" # Linker script
|
|||||||
|
|
||||||
# Standard system options
|
# Standard system options
|
||||||
options "CPU_KHZ=80000" # Oscillator frequency of CPU core
|
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
|
options "BUS_DIV=1" # Bus clock divisor 1/2/4/8
|
||||||
|
|
||||||
# LEDs
|
# LEDs
|
||||||
@@ -33,7 +33,7 @@ config unix root on sd0a
|
|||||||
swap on sd0b
|
swap on sd0b
|
||||||
|
|
||||||
# Console options
|
# Console options
|
||||||
options "CONS_MAJOR=UARTUSB_MAJOR" # UARTUSB device
|
options "CONS_MAJOR=UARTUSB_MAJOR" # USB device
|
||||||
|
|
||||||
# Virtual UART on USB
|
# Virtual UART on USB
|
||||||
device uartusb
|
device uartusb
|
||||||
@@ -50,13 +50,13 @@ signal "SD0_ENA" pin RG13 # SD card enable
|
|||||||
# General purpose I/O ports
|
# General purpose I/O ports
|
||||||
# Flags define a mask of available pins
|
# Flags define a mask of available pins
|
||||||
# The following pins excluded:
|
# 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 gpio0 flags 0xc6ff # port A
|
||||||
device gpio1 flags 0xffff # port B
|
device gpio1 flags 0xffff # port B
|
||||||
device gpio2 flags 0xf01e # port C
|
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 gpio4 flags 0x03ff # port E
|
||||||
device gpio5 flags 0x313f # port F
|
device gpio5 flags 0x303b # port F
|
||||||
device gpio6 flags 0xc3cf # port G
|
device gpio6 flags 0xc3cf # port G
|
||||||
|
|
||||||
# ADC driver
|
# ADC driver
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ PARAM += -DUSB_NUM_STRING_DESCRIPTORS=3
|
|||||||
PARAM += -DUSB_MAX_EP_NUMBER=3
|
PARAM += -DUSB_MAX_EP_NUMBER=3
|
||||||
PARAM += -DCONS_MAJOR=UARTUSB_MAJOR
|
PARAM += -DCONS_MAJOR=UARTUSB_MAJOR
|
||||||
PARAM += -DBUS_DIV=1
|
PARAM += -DBUS_DIV=1
|
||||||
PARAM += -DBUS_KHZ=40000
|
PARAM += -DBUS_KHZ=80000
|
||||||
PARAM += -DCPU_KHZ=80000
|
PARAM += -DCPU_KHZ=80000
|
||||||
LDSCRIPT = "maximite/bootloader.ld"
|
LDSCRIPT = "maximite/bootloader.ld"
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ config unix root on sd0a
|
|||||||
options "CONS_MAJOR=UARTUSB_MAJOR" # USB device
|
options "CONS_MAJOR=UARTUSB_MAJOR" # USB device
|
||||||
|
|
||||||
# Virtual UART on USB
|
# Virtual UART on USB
|
||||||
device uartusb0
|
device uartusb
|
||||||
options "USB_MAX_EP_NUMBER=3"
|
options "USB_MAX_EP_NUMBER=3"
|
||||||
options "USB_NUM_STRING_DESCRIPTORS=3"
|
options "USB_NUM_STRING_DESCRIPTORS=3"
|
||||||
|
|
||||||
@@ -62,3 +62,20 @@ device adc
|
|||||||
|
|
||||||
# PWM driver
|
# PWM driver
|
||||||
device pwm
|
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 += -DGPIO6_ENABLED
|
||||||
PARAM += -DADC_ENABLED
|
PARAM += -DADC_ENABLED
|
||||||
PARAM += -DPWM_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 += -DSD0_ENA_PORT=TRISB -DSD0_ENA_PIN=13
|
||||||
PARAM += -DLED_DISK_PORT=TRISB -DLED_DISK_PIN=12
|
PARAM += -DLED_DISK_PORT=TRISB -DLED_DISK_PIN=12
|
||||||
PARAM += -DLED_KERNEL_PORT=TRISB -DLED_KERNEL_PIN=15
|
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 \
|
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 \
|
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 \
|
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 \
|
gpio.o pwm.o sd.o spi.o spi_bus.o usb_device.o \
|
||||||
usb_function_cdc.o usb_uart.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/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/devsw.c $S/pic32/exception.c $S/pic32/machdep.c \
|
||||||
$S/pic32/mem.c $S/pic32/signal.c $S/pic32/swap.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/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_device.c $S/pic32/usb_function_cdc.c \
|
||||||
$S/pic32/usb_uart.c swapunix.c
|
$S/pic32/usb_uart.c swapunix.c
|
||||||
@@ -329,6 +346,18 @@ sysctl.o: $S/pic32/sysctl.c
|
|||||||
adc.o: $S/pic32/adc.c
|
adc.o: $S/pic32/adc.c
|
||||||
${COMPILE_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
|
gpio.o: $S/pic32/gpio.c
|
||||||
${COMPILE_C}
|
${COMPILE_C}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,13 @@ pic32/sysctl.c standard
|
|||||||
#
|
#
|
||||||
pic32/adc.c optional adc
|
pic32/adc.c optional adc
|
||||||
pic32/glcd.c optional glcd
|
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/gpio.c optional gpio
|
||||||
pic32/hx8357.c optional hxtft
|
pic32/hx8357.c optional hxtft
|
||||||
pic32/picga.c optional picga
|
pic32/picga.c optional picga
|
||||||
@@ -81,7 +88,6 @@ pic32/sdramp.c optional dr
|
|||||||
pic32/sdram.S optional dr
|
pic32/sdram.S optional dr
|
||||||
pic32/spirams.c optional sr
|
pic32/spirams.c optional sr
|
||||||
pic32/sramc.c optional rc
|
pic32/sramc.c optional rc
|
||||||
pic32/st7781.c optional swtft
|
|
||||||
pic32/skel.c optional skel
|
pic32/skel.c optional skel
|
||||||
pic32/spi.c optional spi
|
pic32/spi.c optional spi
|
||||||
pic32/spi_bus.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
|
# Use UECIDE package from http://uecide.org/download
|
||||||
ifndef MIPS_GCC_PREFIX
|
ifndef MIPS_GCC_PREFIX
|
||||||
ifdef UECIDE
|
ifeq ($(HOME)/.uecide/compilers/pic32-tools/bin/pic32-gcc,$(wildcard $(HOME)/.uecide/compilers/pic32-tools/bin/pic32-gcc))
|
||||||
MIPS_GCC_PREFIX = $(UECIDE)/compilers/pic32-tools/bin/pic32-
|
MIPS_GCC_PREFIX = $(HOME)/.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
|
|
||||||
MIPS_GCC_FORMAT = elf32-tradlittlemips
|
MIPS_GCC_FORMAT = elf32-tradlittlemips
|
||||||
endif
|
endif
|
||||||
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