68 Commits

Author SHA1 Message Date
Serge
427487850c Use pic32-tools from uecide.org.
Cannot build user binaries yet though.
2022-05-23 20:29:21 -07:00
Serge Vakulenko
a0c256c1f0 Virus editor crashed when colon command line exceeded 4 bytes.
Fixed issue #79.
2019-02-17 14:24:26 -08:00
Serge Vakulenko
9d8ad7ccf5 Configure gpanel driver for Duinomite board. 2018-01-30 20:35:01 -08:00
Serge Vakulenko
a5d7f4ea99 Gpanel driver: add support for ILI9481 LCD controller. 2018-01-30 20:22:36 -08:00
Serge Vakulenko
435d3c34cf Fix build errors and warnings in zoneinfo and virtualmips. 2018-01-30 20:20:38 -08:00
Serge Vakulenko
0e39621fea Merge pull request #77 from 610t/master
Retern to legacy implement for expr(1) etc.
2017-02-14 23:25:59 -08:00
Takeshi MUTOH
7477abe7f3 Retern to legacy implement for expr(1) etc. 2017-02-12 06:19:13 +09:00
Serge Vakulenko
7075769d7c Merge pull request #76 from vasily122/insert-int
insert definitions of INT in some functions
2016-12-31 14:10:02 -08:00
vasily122
f5452b74de insert definitions of INT in some functions 2016-11-04 13:46:37 +00:00
Matt Jenkins
f3dbdc7615 Got Yacc compiling and running 2016-07-14 00:06:12 +01:00
Matt Jenkins
66e5cd88c0 Fixed UECIDE compiler location detection 2016-07-14 00:04:45 +01:00
Matt Jenkins
0583055d00 Added PONTECH Quick240 2016-07-14 00:02:22 +01:00
Matt Jenkins
aea2050c49 Merge branch 'master' of github.com:RetroBSD/retrobsd 2016-07-13 16:02:46 +01:00
Serge Vakulenko
5fde14ecea Fix bus frequency and gpio configuration for eMega board. 2016-07-12 17:39:08 -07:00
Serge Vakulenko
ca67f33a30 Autobuild: add Olimex Duinomite-eMega board. 2016-07-07 20:46:14 -07:00
Matt Jenkins
20238b7208 Merge branch 'master' of github.com:RetroBSD/retrobsd 2016-07-03 16:48:42 +01:00
Serge Vakulenko
1a7125b892 Merge pull request #74 from ibara/master
RetroBSD now builds on FreeBSD.
2016-06-23 10:23:34 -07:00
Brian Callahan
d048ee200e RetroBSD now builds on FreeBSD. 2016-06-13 06:47:48 -04:00
Matt Jenkins
6ddcb56e2a Made elf2aout compilable for windows under linux 2016-02-15 15:12:21 +00:00
Serge Vakulenko
148bb1cac6 Merge pull request #72 from alexfru/master
Improve *printf()
2016-01-24 22:16:14 -08:00
Alexey Frunze
b2bde490b4 Improve *printf()
- support %i in addition to %d
- print the sign when printing 0 with %+d
2016-01-24 18:38:58 -08:00
Serge Vakulenko
e1d3583dcd Merge pull request #71 from alexfru/master
Fix infinite loop in ldexp(0.0, any).
2016-01-24 01:55:25 -08:00
Alexey Frunze
21f8d60095 Fix infinite loop in ldexp(0.0, any). 2016-01-24 01:43:24 -08:00
Serge Vakulenko
6457d878c0 Merge pull request #70 from alexfru/master
Floating point improvements
2016-01-23 22:57:05 -08:00
Alexey Frunze
e5c844eff2 Floating point improvements
- Smaller C: fix a bug in __func__ introduced with
  float-related changes
- make *printf() print floats greater than 1e25
- make *printf() print the plus sign when the format
  includes "+", e.g. printf("%+f\n", 1.0);
- clean up and complete prototypes in <math.h>
- remove non-standard HUGE and LOGHUGE from <math.h>
- add HUGE_VAL to <math.h>
- express some hard-coded limits in terms of constants
  from <float.h>
- uncomment prototypes of several floating point
  conversion functions in <stdlib.h> for Smaller C
2016-01-23 19:47:14 -08:00
Serge Vakulenko
4e90456341 Merge pull request #69 from alexfru/master
Floats in Smaller C!
2016-01-16 23:35:14 -08:00
Alexey Frunze
bfc3125556 Floats in Smaller C!
double is an alias for float. IOW, only 32-bit
single precision floats are supported. This isn't
conformant, but OK for some embedded systems (e.g.
RetroBSD) and simple compilers like this.

Also, the following operators are not supported with
floats at the moment: ++, --, +=, -=, *=, /=.
But +, -, *, /, =, ||, &&, ?:, !, comparison, casts,
if/while/for are OK.
2016-01-16 22:45:42 -08:00
Serge Vakulenko
fa094d1744 libc: add missing functions __fixunssfsi() and __floatunsisf(). 2016-01-03 00:21:39 -08:00
Serge Vakulenko
b7a3d6f665 Enable uarts for pic32-retrobsd board.
Fix build issues with fuse library path on Mac OS X.
2015-12-30 19:20:37 -08:00
Serge Vakulenko
fb05f20fbe Merge pull request #66 from ibara/master
Update to emg-2.0
2015-12-17 22:21:49 -08:00
Brian Callahan
e050ac6ee6 Update to emg-2.0 2015-12-18 01:13:00 -05:00
Serge Vakulenko
8dd0fb4860 Flappy game: reduce flickering. 2015-12-03 21:43:43 -08:00
Serge Vakulenko
6028db705a Gpanel spi driver: read ID4 register to identify the ili9341 chip. 2015-12-03 21:25:57 -08:00
Serge Vakulenko
6d501bfc7c Update flappy game. 2015-11-30 12:47:45 -08:00
Serge Vakulenko
09205046a4 Move ILI9341 defines to a separate include file. 2015-11-28 00:44:40 -08:00
Serge Vakulenko
ac9ef0eee9 Add sgpanel driver: a generic TFT LCD graphics panel with SPI interface.
Currently only ILI8341 chip is supported.
2015-11-28 00:17:01 -08:00
Serge Vakulenko
e073fcbd64 SD driver: print information about the CMD6 function groups. 2015-11-27 17:26:09 -08:00
Serge Vakulenko
0507073b60 SD driver: use CMD6 command to switch the card into high-speed mode. 2015-11-26 17:25:25 -08:00
Serge Vakulenko
76cb491c09 Flappy Bird game: save high score to a file. 2015-11-23 13:41:13 -08:00
Serge Vakulenko
f3f28ceca5 Fix bug in gpanel fill triangle routine. 2015-11-22 15:04:41 -08:00
Serge Vakulenko
e3c86f0ffa Update Flappy Bird game. 2015-11-22 14:34:44 -08:00
Serge Vakulenko
7503ce7856 Add Flappy Bird game. 2015-11-22 01:47:52 -08:00
Serge Vakulenko
1a1daf15a3 Update ILI9341 LCD driver. 2015-11-22 00:19:14 -08:00
Serge Vakulenko
a40bcee878 Extend gpanel library with fill rectangle routine. 2015-11-21 23:10:45 -08:00
Serge Vakulenko
e67e939fb9 Add aclock game. 2015-11-20 22:44:37 -08:00
Serge Vakulenko
9027547fa6 Mend a font direction in ST7781 portrait unside down mode. 2015-11-20 21:54:34 -08:00
Serge Vakulenko
7c2aa43862 Fix bug in ST7781 driver. Set landscape mode by default. 2015-11-20 21:43:27 -08:00
Serge Vakulenko
8988b8b013 Reuse ili9341 routines for nt35702 display. 2015-11-19 22:10:52 -08:00
Serge Vakulenko
d2940a8719 Fix screen orientation in the ILI9341 LCD driver. 2015-11-19 19:55:07 -08:00
Serge Vakulenko
be1726a662 Draw a BSD logo on the LCD display at start. 2015-11-19 19:04:23 -08:00
Serge Vakulenko
2fd36d9175 Update ILI9341 LCD driver. 2015-11-17 19:25:39 -08:00
Serge Vakulenko
6f0a48330c LCD driver: add support for Samsung S6D04H0 (not finished yet). 2015-11-16 22:15:40 -08:00
Serge Vakulenko
4dd9308e25 Merge branch 'master' of https://github.com/RetroBSD/retrobsd 2015-11-15 14:15:13 -08:00
Serge Vakulenko
98f3efcb70 Increase the max number of processes (NPROC) from 10 to 25. 2015-11-15 14:14:18 -08:00
Serge Vakulenko
2e716e099c LCD driver: fix garbage when a glyph extends off screen. 2015-11-15 13:39:08 -08:00
Serge Vakulenko
03ed62db5d Libm: add 32-bit variant of fmod() function. 2015-11-06 20:40:45 -08:00
Serge Vakulenko
c46bd3c1e9 Enable optimization by size (-Os) by default for all user binaries. 2015-11-03 22:03:52 -08:00
Serge Vakulenko
a673c028f8 Add ubw32 board to the autobuild list. 2015-11-03 21:37:50 -08:00
Serge Vakulenko
7ddf7686a3 Enable mips16e instruction set for all user binaries. 2015-11-03 21:36:31 -08:00
Serge Vakulenko
abcfb06b0b Merge gpanel branch. 2015-10-31 21:12:50 -07:00
Serge Vakulenko
e00196ee21 Merge branch 'master' into gpanel-driver 2015-10-31 21:11:38 -07:00
Serge Vakulenko
5b04c6b168 Add driver for ILI9341 display controller. 2015-10-31 21:09:44 -07:00
Serge Vakulenko
7f69510488 Gpanel driver: use gamma values from NT35702 datasheet. 2015-10-31 19:58:41 -07:00
Serge Vakulenko
058b6c4de0 Add support for NT35702 display controller. 2015-10-31 19:25:26 -07:00
Serge Vakulenko
1e4005cc4b Split the gpanel driver into chip-specific and generic parts. 2015-10-31 14:57:45 -07:00
Serge Vakulenko
66a7727085 Rename swtft -> gpanel. 2015-10-31 13:26:27 -07:00
Serge Vakulenko
2bfd3df2a6 Merge pull request #65 from alexfru/master
virtualmips: improve MIPS16e: save/restore, sdbbp
2015-10-31 00:52:49 -07:00
Alexey Frunze
162f0d34b5 virtualmips: improve MIPS16e: save/restore, sdbbp 2015-10-31 00:45:15 -07:00
158 changed files with 16172 additions and 4337 deletions

View File

@@ -4,16 +4,16 @@
* specifies the terms and conditions for redistribution.
*/
double fabs(), floor(), ceil(), fmod(), ldexp();
double sqrt(), hypot(), atof();
double sin(), cos(), tan(), asin(), acos(), atan(), atan2();
double exp(), log(), log10(), pow();
double sinh(), cosh(), tanh();
double gamma();
double j0(), j1(), jn(), y0(), y1(), yn();
double fabs(double), floor(double), ceil(double);
double sqrt(double), hypot(double, double);
double sin(double), cos(double), tan(double);
double asin(double), acos(double), atan(double), atan2(double, double);
double exp(double), log(double), log10(double), pow(double, double);
double sinh(double), cosh(double), tanh(double);
double j0(double), j1(double), jn(int, double);
double y0(double), y1(double), yn(int, double);
#define HUGE 1.701411733192644270e38
#define LOGHUGE 39
#define HUGE_VAL 3.40282347e+38 /* TBD??? use infinity? */
int isnanf(float x);
int isnan(double x);

View File

@@ -96,12 +96,10 @@ long random (void);
char *setstate (char *);
void srandom (unsigned);
#ifndef __SMALLER_C__
double atof (const char *);
double strtod (const char *, char **);
char *ecvt (double, int, int *, int *);
char *fcvt (double, int, int *, int *);
char *gcvt (double, int, char *);
#endif
#endif /* _STDLIB_H_ */

View File

@@ -2,7 +2,7 @@ TOPSRC = $(shell cd ..; pwd)
SUBDIR = startup libc libm libcurses libtermlib libwiznet libreadline libgpanel
PROG = ar as aout ld nm ranlib size strip
CFLAGS += -std=gnu89 -fno-builtin -g -Werror -Wall -DCROSS -I. \
CFLAGS = -Os -std=gnu89 -fno-builtin -g -Werror -Wall -DCROSS -I. \
-idirafter $(TOPSRC)/include \
-idirafter $(TOPSRC)/src/cmd/ar \
-idirafter $(TOPSRC)/src/cmd/as

View File

@@ -8,7 +8,7 @@ vpath %.c $(LIBCDIR)/mips/sys $(LIBCDIR)/gen $(LIBCDIR)/stdio \
$(LIBCDIR)/stdlib $(LIBCDIR)/string $(LIBCDIR)/inet \
$(LIBCDIR)/compat $(LIBCDIR)/runtime
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
ASFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -I$(LIBCDIR)/mips/sys
# modules which can not use SYSCALL and must be assembled from sources. The
@@ -95,7 +95,8 @@ OBJS += creat.o ftime.o gethostid.o memccpy.o memchr.o \
# libc/runtime
OBJS += addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \
mulsf3.o negsf2.o subsf3.o sc_case.o
mulsf3.o negsf2.o subsf3.o sc_case.o fixunssfsi.o \
floatunsisf.o
all: ../libc.a

View File

@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
vpath %.c $(TOPSRC)/src/libcurses
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
OBJS = addch.o addstr.o box.o clear.o clrtobot.o clrtoeol.o cr_put.o \
cr_tty.o curses.o delch.o deleteln.o delwin.o endwin.o erase.o \

View File

@@ -3,10 +3,10 @@ include $(TOPSRC)/target.mk
vpath %.c $(TOPSRC)/src/libgpanel
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
OBJS = open.o clear.o pixel.o line.o rect.o fill.o circle.o \
image.o char.o text.o text_width.o
OBJS = open.o clear.o pixel.o line.o rect.o fill.o fill_triangle.o \
circle.o image.o char.o text.o text_width.o
all: ../libgpanel.a

View File

@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
vpath %.c $(TOPSRC)/src/libm
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
OBJS = asin.o atan.o exp.o erf.o floor.o fmod.o hypot.o j0.o j1.o \
jn.o log.o pow.o sin.o sinh.o sqrt.o tan.o tanh.o

View File

@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
vpath %.c $(TOPSRC)/src/libreadline
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
OBJS = readline.o

View File

@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
vpath %.c $(TOPSRC)/src/libtermlib
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
OBJS = termcap.o tgoto.o tputs.o tcattr.o

View File

@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
vpath %.c $(TOPSRC)/src/libwiznet
CFLAGS += -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
CFLAGS = -Os -B$(TOPSRC)/lib/ $(DEFS) -Wa,-x -Wall -Werror
OBJS = w5100.o socket.o ethernet.o client.o server.o udp.o

View File

@@ -9,7 +9,7 @@ TOPSRC = $(shell cd ../..; pwd)
include $(TOPSRC)/target.mk
vpath %.c $(TOPSRC)/src/startup-mips
CFLAGS = -B$(TOPSRC)/lib/ -O -Wa,-x $(DEFS)
CFLAGS = -Os -B$(TOPSRC)/lib/ -Wa,-x $(DEFS)
OBJS = ../crt0.o

View File

@@ -605,6 +605,7 @@ file /bin/whoami
file /bin/write
mode 02755
file /bin/xargs
file /bin/yacc
file /bin/zcat
link /bin/[
@@ -671,6 +672,7 @@ default
filemode 0775
dir /games
file /games/adventure
file /games/aclock
file /games/arithmetic
file /games/atc
file /games/backgammon
@@ -1116,6 +1118,7 @@ file /share/examples/gpanel/Makefile
file /share/examples/gpanel/circle.c
file /share/examples/gpanel/color.c
file /share/examples/gpanel/fill.c
file /share/examples/gpanel/flappy.c
file /share/examples/gpanel/font.c
file /share/examples/gpanel/line.c
file /share/examples/gpanel/pixel.c
@@ -1129,6 +1132,7 @@ file /share/examples/gpanel/fonts/digits20.c
file /share/examples/gpanel/fonts/digits32.c
file /share/examples/gpanel/fonts/lucidasans11.c
file /share/examples/gpanel/fonts/lucidasans15.c
file /share/examples/gpanel/fonts/lucidasans28.c
file /share/examples/gpanel/fonts/lucidasans7.c
file /share/examples/gpanel/fonts/lucidasans9.c
file /share/examples/gpanel/fonts/verdana7.c

View File

@@ -1,9 +1,9 @@
CC = cc
LIBS = -lgpanel
PROG = tft tftetris pixel line rect fill circle font color speed
PROG = tft tftetris pixel line rect fill circle font color speed flappy
FONTS = 5x7.o 6x9.o digits20.o digits32.o lucidasans11.o lucidasans15.o \
lucidasans7.o lucidasans9.o verdana7.o
lucidasans28.o lucidasans7.o lucidasans9.o verdana7.o
all: $(PROG)
@@ -37,6 +37,9 @@ color: color.c
speed: speed.c lucidasans15.o
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) speed.c lucidasans15.o $(LIBS)
flappy: flappy.c lucidasans15.o lucidasans28.o
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) flappy.c lucidasans15.o lucidasans28.o $(LIBS)
font: font.c $(FONTS)
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) font.c $(FONTS) $(LIBS)
@@ -58,6 +61,9 @@ lucidasans11.o: fonts/lucidasans11.c
lucidasans15.o: fonts/lucidasans15.c
$(CC) $(CFLAGS) -o $@ -c $?
lucidasans28.o: fonts/lucidasans28.c
$(CC) $(CFLAGS) -o $@ -c $?
lucidasans7.o: fonts/lucidasans7.c
$(CC) $(CFLAGS) -o $@ -c $?

View 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;
}
}
}

View File

@@ -1,5 +1,5 @@
CFLAGS = -Wall -O -g
LDFLAGS = -lpng
LDFLAGS = -L/opt/local/lib -lpng
FONTS = digits32.c \
digits20.c \
@@ -47,6 +47,11 @@ lucidasans15.c: convbdf ttf/Lucida_Sans_Unicode.ttf
./convbdf -u164 -a5 -d5 lucidasans15.bdf
rm -f lucidasans15.bdf
lucidasans28.c: convbdf ttf/Lucida_Sans_Unicode.ttf
-otf2bdf -p 28 -l "$(CHARSET)" ttf/Lucida_Sans_Unicode.ttf > lucidasans28.bdf
./convbdf -u164 -a11 -d9 lucidasans28.bdf
rm -f lucidasans28.bdf
lucidasans9.c: convbdf ttf/Lucida_Sans_Unicode.ttf
-otf2bdf -p 9 -l "$(CHARSET)" ttf/Lucida_Sans_Unicode.ttf > lucidasans9.bdf
./convbdf -u164 -a2 -d3 lucidasans9.bdf

File diff suppressed because it is too large Load Diff

View File

@@ -16,8 +16,8 @@ SUBDIR = adb adc-demo aout ar as awk basic calendar cc chflags \
man md5 med more nm passwd pdc picoc portio printf pwm \
ranlib re renice retroforth scm sed setty sh sl smallc \
smlrc smux stty sysctl test uname wiznet xargs \
zmodem gtest msec unixbench cron compress date2 tip \
talloc uucp
zmodem gtest msec cron compress date2 tip \
talloc uucp yacc
# /sbin
SUBDIR += chown chroot disktool fsck getty init \

View File

@@ -91,6 +91,7 @@ exform(fcount, ifp, itype, ptype)
struct {
long sa;
int sb, sc;
double sd; /* assume double = float = 32 bits */
} fw;
while (fcount > 0) {
@@ -225,18 +226,20 @@ exform(fcount, ifp, itype, ptype)
break;
case 'f':
*(double *)&fw = 0.0;
case 'F':
fw.sd = 0.0;
fw.sa = wx;
print("%-16.9f", *(double *)&fw);
print("%-16.9f", fw.sd);
dotinc = 4;
break;
#if 0
/* 64-bit double not supported */
case 'F':
fw.sa = wx;
print("%-32.18F", *(double *)&fw);
dotinc = 8;
break;
#endif
case 'n': case 'N':
printc('\n');
dotinc = 0;

View File

@@ -38,6 +38,7 @@
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <time.h>
# include <errno.h>
# include <getopt.h>
#else

View File

@@ -97,7 +97,7 @@ typedef struct {
/* Header structure internal format. */
typedef struct {
off_t size; /* size of the object in bytes */
long date; /* date */
time_t date; /* date */
int lname; /* size of the long name in bytes */
int gid; /* group */
int uid; /* owner */

View File

@@ -91,7 +91,8 @@ delete(argv)
SETCF(tfd, tname, afd, archive, NOPAD);
copy_ar(&cf, size);
(void)close(tfd);
(void)ftruncate(afd, size + SARMAG);
if (ftruncate(afd, size + SARMAG) < 0)
/* ignore */;
close_archive(afd);
if (*argv) {

View File

@@ -136,7 +136,8 @@ move(argv)
cf.rfd = tfd3;
copy_ar(&cf, size);
(void)ftruncate(afd, tsize + SARMAG);
if (ftruncate(afd, tsize + SARMAG) < 0)
/* ignore */;
close_archive(afd);
if (*argv) {

View File

@@ -190,7 +190,8 @@ append: while ((file = *argv++) != 0) {
cf.rfd = tfd2;
copy_ar(&cf, size);
(void)ftruncate(afd, tsize + SARMAG);
if (ftruncate(afd, tsize + SARMAG) < 0)
/* ignore */;
close_archive(afd);
return(err);
}

View File

@@ -15,7 +15,6 @@
* only. IE: A is equivalent to A0 ... Z$ is equivalent to Z0$
*
* Statements:
* BEEP freq,ms - Generate a BEEP on the PC speaker
* CLEAR - Erase variables only
* CLOSE#n - Close file (0-9) opened with OPEN
* DATA - Enter "inline" data statements
@@ -155,7 +154,7 @@
#define SAVE 25
#define LOAD 26
#define DELAY 27
#define BEEP 28
//#define BEEP 28
#define DOS 29
#define OUT 30
@@ -279,11 +278,6 @@ int eval_sub(void);
WINDOW *win;
void beep (int i, int t)
{
printf("BEEP not implemented yet, at line %u\n", line);
}
void delay (int msec)
{
usleep (msec * 1000);
@@ -1371,11 +1365,6 @@ input: if (ii == -1)
case SRND:
srandom(eval_num());
break;
case BEEP:
i = eval_num();
expect(',');
beep(i, eval_num());
break;
case DOS:
eval_char();
fflush(stdout);

View File

@@ -1,13 +1,26 @@
ChangeLog
=========
December 17, 2015 : emg 2.0
---------------------------
Remove several unused functions.
Greatly simplify the buffer logic. emg no longer has multi-buffer support.
Remember to reset line number when opening files.
August 21, 2015 : emg 1.9
-------------------------
Smarter terminal setup.
Clarify quit message if you haven't saved the file.
Remove non-standard M-Z quick save.
Simpler arrow key and PgUp/PgDn logic.
August 10, 2015 : emg 1.8
-------------------------
Remove most buffer functions.
Remove all window functions.
Remove window.c, the one remaining function goes to display.c
Rework the modeline to look like Mg.
Add a version function, bound to "M-e".
Add a version function, bound to "M-E".
July 10, 2014 : emg 1.7
-----------------------

View File

@@ -13,11 +13,6 @@ CFLAGS += -ffunction-sections -fdata-sections
# This reduces code size significantly.
CFLAGS += -mips16
# Set the screen size.
# Will default to COLS=80 and ROWS=24
# if not set here.
#CFLAGS += -DCOLS=80 -DROWS=24
# with CFLAGS+= -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections

View File

@@ -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
View 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>

View File

@@ -12,16 +12,16 @@
#include "estruct.h"
#include "edef.h"
extern int getccol(int bflg);
extern int getccol(int);
extern void mlwrite();
extern int mlreplyt();
int forwchar(int f, int n);
int backchar(int f, int n);
int forwline(int f, int n);
int backline(int f, int n);
int pagedown(int f, int n);
int pageup(int f, int n);
int forwchar(int, int);
int backchar(int, int);
int forwline(int, int);
int backline(int, int);
int pagedown(int, int);
int pageup(int, int);
/*
* This routine, given a pointer to a LINE, and the current cursor goal
@@ -254,24 +254,24 @@ int backline(int f, int n)
}
/*
* PgDn. Scroll down (ROWS - 1).
* Just forwline(f, (ROWS -1))
* PgDn. Scroll down (rows / 2).
* Just forwline(f, (rows / 2))
* Bound to C-V
*/
int pagedown(int f, int n)
{
forwline(f, (ROWS - 1));
forwline(f, (rows / 2));
return (TRUE);
}
/*
* PgUp. Scroll up (ROWS - 1).
* Just backline(f, (ROWS -1))
* PgUp. Scroll up (rows / 2).
* Just backline(f, (rows / 2))
* Bound to M-V
*/
int pageup(int f, int n)
{
backline(f, (ROWS - 1));
backline(f, (rows / 2));
return (TRUE);
}

View File

@@ -11,93 +11,17 @@
#include "estruct.h"
#include "edef.h"
extern int mlreply(char *prompt, char *buf, int nbuf);
extern int readin(char fname[]);
extern int mlreply(char *, char *, int);
extern int readin(char []);
extern void mlwrite();
extern void mlerase();
extern int mlyesno(char *prompt);
extern void lfree(LINE *lp);
extern int mlyesno(char *);
extern void lfree(LINE *);
extern LINE *lalloc();
int swbuffer(BUFFER *bp);
int addline(char *text);
int anycb();
BUFFER* bfind(char *bname, int cflag, int bflag);
int bclear(BUFFER *bp);
/*
* make buffer BP current
*/
int swbuffer(BUFFER *bp)
{
WINDOW *wp;
if (--curbp->b_nwnd == 0)
{ /* Last use. */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
curbp = bp; /* Switch. */
if (curbp->b_active != TRUE)
{ /* buffer not active yet */
/* read it in and activate it */
readin(curbp->b_fname);
curbp->b_dotp = lforw(curbp->b_linep);
curbp->b_doto = 0;
curbp->b_active = TRUE;
}
curwp->w_bufp = bp;
curwp->w_linep = bp->b_linep; /* For macros, ignored */
curwp->w_flag |= WFMODE | WFFORCE | WFHARD; /* Quite nasty */
if (bp->b_nwnd++ == 0)
{ /* First use */
curwp->w_dotp = bp->b_dotp;
curwp->w_doto = bp->b_doto;
curwp->w_markp = bp->b_markp;
curwp->w_marko = bp->b_marko;
return (TRUE);
}
wp = wheadp; /* Look for old */
while (wp != 0)
{
if (wp != curwp && wp->w_bufp == bp)
{
curwp->w_dotp = wp->w_dotp;
curwp->w_doto = wp->w_doto;
curwp->w_markp = wp->w_markp;
curwp->w_marko = wp->w_marko;
break;
}
wp = wp->w_wndp;
}
return (TRUE);
}
/*
* The argument "text" points to a string. Append this line to the buffer list
* buffer. Handcraft the EOL on the end. Return TRUE if it worked and FALSE if
* you ran out of room.
*/
int addline(char *text)
{
LINE *lp;
int ntext, i;
ntext = strlen(text);
if ((lp = lalloc(ntext)) == NULL)
return (FALSE);
for (i = 0; i < ntext; ++i)
lputc(lp, i, text[i]);
blistp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */
lp->l_bp = blistp->b_linep->l_bp;
blistp->b_linep->l_bp = lp;
lp->l_fp = blistp->b_linep;
if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */
blistp->b_dotp = lp; /* move it to new line */
return (TRUE);
}
int anycb(void);
BUFFER *bfind(char *);
int bclear(BUFFER *);
/*
* Look through the list of buffers. Return TRUE if there are any changed
@@ -105,13 +29,12 @@ int addline(char *text)
* cares if the list of buffer names is hacked. Return FALSE if no buffers
* have been changed.
*/
int anycb()
int anycb(void)
{
BUFFER *bp;
bp = bheadp;
while (bp != NULL)
{
while (bp != NULL) {
if ((bp->b_flag & BFTEMP) == 0 && (bp->b_flag & BFCHG) != 0)
return (TRUE);
bp = bp->b_bufp;
@@ -122,50 +45,40 @@ int anycb()
/*
* Find a buffer, by name. Return a pointer to the BUFFER structure associated
* with it. If the named buffer is found, but is a TEMP buffer (like the
* buffer list) conplain. If the buffer is not found and the "cflag" is TRUE,
* create it. The "bflag" is the settings for the flags in in buffer.
* buffer list), complain.
*/
BUFFER* bfind(char *bname, int cflag, int bflag)
BUFFER *
bfind(char *fname)
{
BUFFER *bp, *sb;
LINE *lp;
bp = bheadp;
while (bp != 0)
{
if (strcmp(bname, bp->b_bname) == 0)
{
if ((bp->b_flag & BFTEMP) != 0)
{
mlwrite ("Cannot select builtin buffer");
return (0);
while (bp != 0) {
if (strcmp(fname, bp->b_fname) == 0) {
if ((bp->b_flag & BFTEMP) != 0) {
mlwrite("Cannot select builtin buffer");
return (FALSE);
}
return (bp);
}
bp = bp->b_bufp;
}
if (cflag != FALSE)
{
if ((bp = (BUFFER *) malloc(sizeof(BUFFER))) == NULL)
return (0);
if ((lp = lalloc(0)) == NULL)
{
return (FALSE);
if ((lp = lalloc(0)) == NULL) {
free(bp);
return (BUFFER*)0;
return (BUFFER *)0;
}
/* find the place in the list to insert this buffer */
if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0)
{
if (bheadp == NULL || strcmp(bheadp->b_fname, fname) > 0) {
/* insert at the begining */
bp->b_bufp = bheadp;
bheadp = bp;
}
else
{
} else {
sb = bheadp;
while (sb->b_bufp != 0)
{
if (strcmp(sb->b_bufp->b_bname, bname) > 0)
while (sb->b_bufp != 0) {
if (strcmp(sb->b_bufp->b_fname, fname) > 0)
break;
sb = sb->b_bufp;
}
@@ -176,20 +89,15 @@ BUFFER* bfind(char *bname, int cflag, int bflag)
}
/* and set up the other buffer fields */
bp->b_active = TRUE;
bp->b_dotp = lp;
bp->b_doto = 0;
bp->b_markp = 0;
bp->b_marko = 0;
bp->b_flag = (char)bflag;
bp->b_nwnd = 0;
bp->b_flag = 0;
bp->b_linep = lp;
bp->b_lines = 1;
strncpy(bp->b_fname, "", 1);
strncpy(bp->b_bname, bname, NBUFN);
lp->l_fp = lp;
lp->l_bp = lp;
}
return (bp);
}

View File

@@ -17,28 +17,28 @@ extern int typeahead();
extern int ctrlg();
extern int getccol();
void movecursor(int row, int col);
void movecursor(int, int);
void mlerase();
int refresh();
void vtinit();
void vttidy();
void vtmove(int row, int col);
void vtputc(int c);
void vtpute(int c);
int vtputs(const char *s);
void vtmove(int, int);
void vtputc(int);
void vtpute(int);
int vtputs(const char *);
void vteeol();
void update();
void updext();
void updateline(int row, char vline[], char pline[], short *flags);
void modeline(WINDOW *wp);
void updateline(int, char [], char [], short *);
void modeline(WINDOW *);
void upmode();
int mlyesno(char *prompt);
int mlreplyt(char *prompt, char *buf, int nbuf, char eolchar);
int mlreply(char *prompt, char *buf, int nbuf);
int mlyesno(char *);
int mlreplyt(char *, char *, int, char);
int mlreply(char *, char *, int);
void mlwrite();
void mlputs(char *s);
void mlputi(int i, int r);
void mlputli(long l, int r);
void mlputs(char *);
void mlputi(int, int);
void mlputli(long, int);
typedef struct VIDEO {
short v_flag; /* Flags */
@@ -1001,4 +1001,3 @@ void mlputli(long l, int r)
(*term.t_putchar) ((int) (l % r) + '0');
++ttcol;
}

View File

@@ -50,9 +50,12 @@ KEYTAB keytab[] = {
{META | 'S', forwsearch}, /* non-standard */
{META | 'V', pageup},
{META | 'W', copyregion},
{META | 'Z', quickexit},
{METE | 'A', backline},
{METE | 'B', forwline},
{METE | 'C', forwchar},
{METE | 'D', backchar},
{METE | '5', pageup},
{METE | '6', pagedown},
{0x7F, backdel},
{META | '[', extendedcmd},
{META | 'O', extendedcmd},
{0, 0}
};

View File

@@ -26,11 +26,11 @@ int curcol; /* Cursor column */
int thisflag; /* Flags, this command */
int lastflag; /* Flags, last command */
int curgoal; /* Goal for C-P, C-N */
int rows; /* Screen rows for C-V, M-V */
WINDOW *curwp; /* Current window */
BUFFER *curbp; /* Current buffer */
WINDOW *wheadp; /* Head of list of windows */
BUFFER *bheadp; /* Head of list of buffers */
BUFFER *blistp; /* Buffer for C-X C-B */
short *kbdmip; /* Input pointer for above */
short *kbdmop; /* Output pointer for above */
@@ -61,18 +61,14 @@ extern int curcol; /* Cursor column */
extern int thisflag; /* Flags, this command */
extern int lastflag; /* Flags, last command */
extern int curgoal; /* Goal for C-P, C-N */
extern int rows; /* Screen rows for C-V, M-V */
extern WINDOW *curwp; /* Current window */
extern BUFFER *curbp; /* Current buffer */
extern WINDOW *wheadp; /* Head of list of windows */
extern BUFFER *bheadp; /* Head of list of buffers */
extern BUFFER *blistp; /* Buffer for C-X C-B */
extern short *kbdmip; /* Input pointer for above */
extern short *kbdmop; /* Output pointer for above */
#endif
/* terminal table defined only in TERM.C */
#ifndef termdef
extern TERM term; /* Terminal information */
#endif

View File

@@ -44,11 +44,9 @@ extern int killtext(); /* Kill forward */
extern int yank(); /* Yank back from killbuffer */
extern int killregion(); /* Kill region */
extern int copyregion(); /* Copy region to kill buffer */
extern int quickexit(); /* low keystroke style exit */
extern int setline(); /* go to a numbered line */
extern int deskey(); /* describe a key's binding */
extern int insfile(); /* insert a file */
extern int forwhunt(); /* hunt forward for next match */
extern int backhunt(); /* hunt backwards for next match */
extern int extendedcmd(); /* parse ANSI/VT100 extended keys */
extern int showversion(); /* show emacs version */

View File

@@ -3,7 +3,7 @@
.\" Basic emg man page.
.\" As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
.\"
.Dd August 9, 2014
.Dd August 9, 2015
.Os
.Dt EMG 1
.Sh NAME

View File

@@ -1,4 +1,4 @@
emg keybindings (August 9, 2014)
emg keybindings (August 9, 2015)
Based on Ersatz Emacs (2000/09/14)
M- means to use the <ESC> key prior to using another key

View File

@@ -17,6 +17,7 @@
#define CTRL 0x0100 /* Control flag, or'ed in */
#define META 0x0200 /* Meta flag, or'ed in */
#define CTLX 0x0400 /* ^X flag, or'ed in */
#define METE 0x0800 /* M-[ flag, or'ed in */
#define FALSE 0 /* False, no, bad, etc */
#define TRUE 1 /* True, yes, good, etc */
@@ -31,35 +32,6 @@
#define CFCPCN 0x0001 /* Last command was C-P, C-N */
#define CFKILL 0x0002 /* Last command was a kill */
/*
* screen constants
* override with
* CFLAGS += -DCOLS=XXX -DROWS=XXX
*/
#ifndef COLS
#define COLS 80
#endif
#ifndef ROWS
#define ROWS 24
#endif
/*
* XXX:
* Default/sane(?) maximum column and row sizes.
* Taken from mg1a.
*
* Let the user override these with
* CFLAGS += -DMAXCOL=XXX -DMAXROW=XXX
*/
#ifndef MAXCOL
#define MAXCOL 132
#endif
#ifndef MAXROW
#define MAXROW 66
#endif
/*
* There is a window structure allocated for every active display window. The
* windows are kept in a big list, in top to bottom screen order, with the
@@ -95,12 +67,9 @@ typedef struct WINDOW
* Text is kept in buffers. A buffer header, described below, exists for every
* buffer in the system. The buffers are kept in a big list, so that commands
* that search for a buffer by name can find the buffer header. There is a
* safe store for the dot and mark in the header, but this is only valid if
* the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
* the buffer is kept in a circularly linked list of lines, with a pointer to
* the header line in "b_linep". Buffers may be "Inactive" which means the
* files accosiated with them have not been read in yet. These get read in at
* "use buffer" time
* safe store for the dot and mark in the header. The text for the buffer is
* kept in a circularly linked list of lines, with a pointer to the header
* line in "b_linep".
*/
typedef struct BUFFER
{
@@ -110,11 +79,8 @@ typedef struct BUFFER
struct LINE *b_markp; /* The same as the above two, */
long b_marko; /* but for the "mark" */
struct LINE *b_linep; /* Link to the header LINE */
char b_active; /* window activated flag */
char b_nwnd; /* Count of windows on buffer */
char b_flag; /* Flags */
char b_fname[NFILEN]; /* File name */
char b_bname[NBUFN]; /* Buffer name */
int b_lines; /* Number of lines in file */
} BUFFER;

View File

@@ -9,40 +9,37 @@
#include "estruct.h"
#include "edef.h"
extern int mlreply(char *prompt, char *buf, int nbuf);
extern int swbuffer(BUFFER *bp);
extern int mlreply(char *, char *, int);
extern void mlwrite();
extern int bclear(BUFFER *bp);
extern int ffropen(char *fn);
extern int ffgetline(char buf[], int nbuf);
extern int ffwopen(char *fn);
extern int bclear(BUFFER *);
extern int ffropen(char *);
extern int ffgetline(char [], int);
extern int ffwopen(char *);
extern int ffclose();
extern int ffputline(char buf[], int nbuf);
extern int ffputline(char [], int);
extern BUFFER *bfind();
extern LINE *lalloc();
int fileread(int f, int n);
int insfile(int f, int n);
int getfile(char fname[]);
int readin(char fname[]);
void makename(char bname[], char fname[]);
int filewrite(int f, int n);
int filesave(int f, int n);
int writeout(char *fn);
int filename(int f, int n);
int ifile(char fname[]);
int fileread(int, int);
int insfile(int, int);
int readin(char []);
int filewrite(int, int);
int filesave(int, int);
int writeout(char *);
int filename(int, int);
int ifile(char []);
/*
* Read a file into the current buffer. This is really easy; all you do it
* find the name of the file, and call the standard "read a file into the
* current buffer" code. Bound to "C-X C-R"
* current buffer" code. Bound to "C-X C-F"
*/
int fileread(int f, int n)
{
int s;
char fname[NFILEN];
if ((s = mlreply("Read file: ", fname, NFILEN)) != TRUE)
if ((s = mlreply("Open file: ", fname, NFILEN)) != TRUE)
return (s);
return (readin(fname));
}
@@ -62,65 +59,6 @@ int insfile(int f, int n)
return (ifile(fname));
}
int getfile(char fname[])
{
BUFFER *bp;
LINE *lp;
char bname[NBUFN]; /* buffer name to put file */
int i, s;
for (bp = bheadp; bp != (BUFFER*)0; bp = bp->b_bufp)
{
if ((bp->b_flag & BFTEMP) == 0 && strcmp(bp->b_fname, fname) == 0)
{
if (--curbp->b_nwnd == 0)
{
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
swbuffer(bp);
lp = curwp->w_dotp;
i = curwp->w_ntrows / 2;
while (i-- && lback(lp) != curbp->b_linep)
lp = lback(lp);
curwp->w_linep = lp;
curwp->w_flag |= WFMODE | WFHARD;
mlwrite("[Old buffer]");
return (TRUE);
}
}
makename(bname, fname); /* New buffer name */
while ((bp = bfind(bname, FALSE, 0)) != (BUFFER*)0)
{
s = mlreply("Buffer name: ", bname, NBUFN);
if (s == ABORT) /* ^G to just quit */
return (s);
if (s == FALSE)
{ /* CR to clobber it */
makename(bname, fname);
break;
}
}
if (bp == (BUFFER*)0 && (bp = bfind(bname, TRUE, 0)) == (BUFFER*)0)
{
mlwrite("Cannot create buffer");
return (FALSE);
}
if (--curbp->b_nwnd == 0)
{ /* Undisplay */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
curbp = bp; /* Switch to it */
curwp->w_bufp = bp;
curbp->b_nwnd++;
return (readin(fname)); /* Read it in */
}
/*
* Read file "fname" into the current buffer, blowing away any text found
* there. Called by both the read and find commands. Return the final status
@@ -196,6 +134,7 @@ int readin(char fname[])
wp->w_doto = 0;
wp->w_markp = NULL;
wp->w_marko = 0;
wp->w_dotline = 0;
wp->w_flag |= WFMODE | WFHARD;
}
}
@@ -204,27 +143,6 @@ int readin(char fname[])
return (TRUE);
}
/*
* Take a file name, and from it fabricate a buffer name. This routine knows
* about the syntax of file names on the target system. I suppose that this
* information could be put in a better place than a line of code.
*/
void makename(char bname[], char fname[])
{
char *cp1, *cp2;
cp1 = &fname[0];
while (*cp1 != 0)
++cp1;
while (cp1 != &fname[0] && cp1[-1] != '/')
--cp1;
cp2 = &bname[0];
while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != ';')
*cp2++ = *cp1++;
*cp2 = 0;
}
/*
* Ask for a file name, and write the contents of the current buffer to that
* file. Update the remembered file name and clear the buffer changed flag.
@@ -267,7 +185,7 @@ int filesave(int f, int n)
if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes */
return (TRUE);
if (curbp->b_fname[0] == 0)
if (curbp->b_fname[0] == '\0')
filename(f, n); /* Must have a name */
if ((s = writeout(curbp->b_fname)) == TRUE)
{

View File

@@ -11,11 +11,11 @@
extern void mlwrite();
int ffropen(char *fn);
int ffwopen(char *fn);
int ffropen(char *);
int ffwopen(char *);
int ffclose();
int ffputline(char buf[], int nbuf);
int ffgetline(char buf[], int nbuf);
int ffputline(char [], int);
int ffgetline(char [], int);
FILE *ffp; /* File pointer, all functions */

View File

@@ -6,12 +6,6 @@
* and window structures, to make sure that the necessary updating gets done.
* There are routines in this file that handle the kill buffer too. It isn't
* here for any good reason.
*
* Note that this code only updates the dot and mark values in the window
* list. Since all the code acts on the current window, the buffer that we are
* editing must be being displayed, which means that "b_nwnd" is non zero,
* which means that the dot and mark values in the buffer headers are
* nonsense
*/
#include <stdlib.h> /* malloc(3) */
@@ -19,18 +13,18 @@
#include "edef.h"
extern void mlwrite();
extern int backchar(int f, int n);
extern int backchar(int, int);
LINE* lalloc(int used);
void lfree(LINE *lp);
void lchange(int flag);
int linsert(int n, int c);
LINE* lalloc(int);
void lfree(LINE *);
void lchange(int);
int linsert(int, int);
int lnewline();
int ldelete(int n, int kflag);
int ldelete(int, int);
int ldelnewline();
void kdelete();
int kinsert(int c);
int kremove(int n);
int kinsert(int);
int kremove(int);
#define NBLOCK 16 /* Line block chunk size */
#define KBLOCK 1024 /* Kill buffer block size */
@@ -45,7 +39,8 @@ unsigned long ksize = 0; /* # of bytes allocated in KB */
* a pointer to the new block, or NULL if there isn't any memory left. Print a
* message in the message line if no space.
*/
LINE* lalloc(int used)
LINE *
lalloc(int used)
{
LINE *lp;
int size;
@@ -69,7 +64,8 @@ LINE* lalloc(int used)
* might be in. Release the memory. The buffers are updated too; the magic
* conditions described in the above comments don't hold here
*/
void lfree(LINE *lp)
void
lfree(LINE *lp)
{
BUFFER *bp;
WINDOW *wp;
@@ -92,21 +88,15 @@ void lfree(LINE *lp)
wp = wp->w_wndp;
}
bp = bheadp;
while (bp != NULL)
{
if (bp->b_nwnd == 0)
{
if (bp->b_dotp == lp)
{
while (bp != NULL) {
if (bp->b_dotp == lp) {
bp->b_dotp = lp->l_fp;
bp->b_doto = 0;
}
if (bp->b_markp == lp)
{
if (bp->b_markp == lp) {
bp->b_markp = lp->l_fp;
bp->b_marko = 0;
}
}
bp = bp->b_bufp;
}
lp->l_bp->l_fp = lp->l_fp;
@@ -117,24 +107,20 @@ void lfree(LINE *lp)
/*
* This routine gets called when a character is changed in place in the
* current buffer. It updates all of the required flags in the buffer and
* window system. The flag used is passed as an argument; if the buffer is
* being displayed in more than 1 window we change EDIT t HARD. Set MODE if
* the mode line needs to be updated (the "*" has to be set).
* window system. The flag used is passed as an argument. Set MODE if the
* mode line needs to be updated (the "**" has to be set).
*/
void lchange(int flag)
void
lchange(int flag)
{
WINDOW *wp;
if (curbp->b_nwnd != 1) /* Ensure hard */
flag = WFHARD;
if ((curbp->b_flag & BFCHG) == 0)
{ /* First change, so */
if ((curbp->b_flag & BFCHG) == 0) { /* First change, so */
flag |= WFMODE; /* update mode lines */
curbp->b_flag |= BFCHG;
}
wp = wheadp;
while (wp != NULL)
{
while (wp != NULL) {
if (wp->w_bufp == curbp)
wp->w_flag |= flag;
wp = wp->w_wndp;
@@ -150,7 +136,8 @@ void lchange(int flag)
* greater than the place where you did the insert. Return TRUE if all is
* well, and FALSE on errors
*/
int linsert(int n, int c)
int
linsert(int n, int c)
{
WINDOW *wp;
LINE *lp1, *lp2, *lp3;
@@ -238,7 +225,8 @@ int linsert(int n, int c)
* update of dot and mark is a bit easier then in the above case, because the
* split forces more updating.
*/
int lnewline()
int
lnewline()
{
WINDOW *wp;
char *cp1, *cp2;
@@ -296,7 +284,8 @@ int lnewline()
* deleted, and FALSE if they were not (because dot ran into the end of the
* buffer. The "kflag" is TRUE if the text should be put in the kill buffer.
*/
int ldelete(int n, int kflag)
int
ldelete(int n, int kflag)
{
LINE *dotp;
WINDOW *wp;
@@ -368,7 +357,8 @@ int ldelete(int n, int kflag)
* require that lines be moved about in memory. Return FALSE on error and TRUE
* if all looks ok. Called by "ldelete" only.
*/
int ldelnewline()
int
ldelnewline()
{
LINE *lp1, *lp2, *lp3;
WINDOW *wp;
@@ -457,10 +447,10 @@ int ldelnewline()
* new kill context is being created. The kill buffer array is released, just
* in case the buffer has grown to immense size. No errors.
*/
void kdelete()
void
kdelete()
{
if (kbufp != NULL)
{
if (kbufp != NULL) {
free((char *) kbufp);
kbufp = NULL;
kused = 0;
@@ -474,7 +464,8 @@ void kdelete()
* put something in the kill buffer you are going to put more stuff there too
* later. Return TRUE if all is well, and FALSE on errors.
*/
int kinsert(int c)
int
kinsert(int c)
{
char *nbufp;
@@ -498,7 +489,8 @@ int kinsert(int c)
* "n" is off the end, it returns "-1". This lets the caller just scan along
* until it gets a "-1" back.
*/
int kremove(int n)
int
kremove(int n)
{
if (n >= kused)
return (-1);

View File

@@ -22,84 +22,63 @@ extern void vttidy();
extern void update();
extern void mlerase();
extern void mlwrite();
extern int mlyesno(char *prompt);
extern void makename(char bname[], char fname[]);
extern int readin(char fname[]);
extern int linsert(int f, int n);
extern int anycb();
extern BUFFER *bfind();
extern int mlyesno(char *);
extern int readin(char []);
extern int linsert(int, int);
extern int anycb(void);
extern BUFFER *bfind(char *);
void edinit(char bname[]);
int execute(int c, int f, int n);
int getkey();
int getctl();
int quickexit(int f, int n);
int quit(int f, int n);
int ctlxlp(int f, int n);
int ctlxrp(int f, int n);
int ctlxe(int f, int n);
int ctrlg(int f, int n);
int extendedcmd(int f, int n);
void edinit(char []);
int execute(int, int, int);
int getkey(void);
int getctl(void);
int quit(int, int);
int ctlxlp(int, int);
int ctlxrp(int, int);
int ctlxe(int, int);
int ctrlg(int, int);
int
main(int argc, char *argv[])
{
BUFFER *bp;
char bname[NBUFN]; /* buffer name of file to read */
char fname[NFILEN];
int c, f, n, mflag;
int ffile; /* first file flag */
int basec; /* c stripped of meta character */
/* initialize the editor and process the startup file */
getwinsize(); /* find out the "real" screen size */
strncpy(bname, "main", 5); /* default buffer name */
edinit(bname); /* Buffers, windows */
vtinit(); /* Displays */
ffile = TRUE; /* no file to edit yet */
update(); /* let the user know we are here */
/* scan through the command line and get the files to edit */
/* In place of getopt() */
if (argc > 2) {
(void) fprintf(stderr, "Can only edit one file at a time\n");
(void) fprintf(stderr, "usage: emg [file]\n");
exit(1);
} else if (argc == 2) {
/* set up a buffer for this file */
makename(bname, argv[1]);
/* if this is the first file, read it in */
if (ffile)
{
bp = curbp;
makename(bname, argv[1]);
strncpy(bp->b_bname, bname, NBUFN);
strncpy(bp->b_fname, argv[1], NFILEN);
if (readin(argv[1]) == ABORT)
{
strncpy(bp->b_bname, "main", 5);
strncpy(bp->b_fname, "", 1);
strncpy(fname, argv[1], NFILEN);
} else {
strncpy(fname, "*scratch*", NFILEN);
}
/* initialize the editor and process the startup file */
getwinsize(); /* Find out the "real" screen size */
edinit(fname); /* Buffers, windows */
vtinit(); /* Displays */
update(); /* Let the user know we are here */
/* Read in the file given on the command line */
if (argc == 2) {
bp = curbp;
if (readin(argv[1]) == ABORT)
strncpy(fname, "*scratch*", NFILEN);
bp->b_dotp = bp->b_linep;
bp->b_doto = 0;
ffile = FALSE;
}
else
{
/* set this to inactive */
bp = bfind(bname, TRUE, 0);
strncpy(bp->b_fname, argv[1], NFILEN);
bp->b_active = FALSE;
}
}
/* setup to process commands */
lastflag = 0; /* Fake last flags */
curwp->w_flag |= WFMODE; /* and force an update */
loop:
loop:
update(); /* Fix up the screen */
c = getkey();
if (mpresf != FALSE)
{
if (mpresf != FALSE) {
mlerase();
update();
}
@@ -109,22 +88,18 @@ main(int argc, char *argv[])
/* do META-# processing if needed */
basec = c & ~META; /* strip meta char off if there */
if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-'))
{
if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-')) {
f = TRUE; /* there is a # arg */
n = 0; /* start with a zero default */
mflag = 1; /* current minus flag */
c = basec; /* strip the META */
while ((c >= '0' && c <= '9') || (c == '-'))
{
if (c == '-')
{
while ((c >= '0' && c <= '9') || (c == '-')) {
if (c == '-') {
/* already hit a minus or digit? */
if ((mflag == -1) || (n != 0))
break;
mflag = -1;
}
else
} else
n = n * 10 + (c - '0');
if ((n == 0) && (mflag == -1)) /* lonely - */
mlwrite("Arg:");
@@ -135,38 +110,32 @@ main(int argc, char *argv[])
}
n = n * mflag; /* figure in the sign */
}
/* do ^U repeat argument processing */
if (c == (CTRL | 'U'))
{ /* ^U, start argument */
/* do ^U repeat argument processing */
if (c == (CTRL | 'U')) { /* ^U, start argument */
f = TRUE;
n = 4; /* with argument of 4 */
mflag = 0; /* that can be discarded */
mlwrite("Arg: 4");
while (((c = getkey ()) >= '0')
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-')))
{
while (((c = getkey()) >= '0')
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-'))) {
if (c == (CTRL | 'U'))
n = n * 4;
/*
* If dash, and start of argument string, set arg.
* to -1. Otherwise, insert it.
*/
else if (c == '-')
{
else if (c == '-') {
if (mflag)
break;
n = 0;
mflag = -1;
}
/*
* If first digit entered, replace previous argument
* with digit and set sign. Otherwise, append to arg.
*/
else
{
if (!mflag)
{
} else {
if (!mflag) {
n = 0;
mflag = 1;
}
@@ -178,25 +147,24 @@ main(int argc, char *argv[])
* Make arguments preceded by a minus sign negative and change
* the special argument "^U -" to an effective "^U -1".
*/
if (mflag == -1)
{
if (mflag == -1) {
if (n == 0)
n++;
n = -n;
}
}
if (c == (CTRL | 'X')) /* ^X is a prefix */
c = CTLX | getctl ();
if (kbdmip != NULL)
{ /* Save macro strokes */
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6])
{
if (c == (META | '[')) /* M-[ is extended ANSI sequence */
c = METE | getctl();
else if (c == (CTRL | 'X')) /* ^X is a prefix */
c = CTLX | getctl();
if (kbdmip != NULL) { /* Save macro strokes */
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6]) {
ctrlg(FALSE, 0);
goto loop;
}
if (f != FALSE)
{
if (f != FALSE) {
*kbdmip++ = (CTRL | 'U');
*kbdmip++ = n;
}
@@ -211,22 +179,21 @@ main(int argc, char *argv[])
* as an argument, because the main routine may have been told to read in a
* file by default, and we want the buffer name to be right.
*/
void edinit(char bname[])
void
edinit(char fname[])
{
BUFFER *bp;
WINDOW *wp;
bp = bfind(bname, TRUE, 0); /* First buffer */
blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */
wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
if (bp == NULL || wp == NULL || blistp == NULL)
exit (1);
bp = bfind(fname);
wp = (WINDOW *) malloc(sizeof(WINDOW));
if (bp == NULL || wp == NULL)
exit(1);
curbp = bp; /* Make this current */
wheadp = wp;
curwp = wp;
wp->w_wndp = NULL; /* Initialize window */
wp->w_bufp = bp;
bp->b_nwnd = 1; /* Displayed */
wp->w_linep = bp->b_linep;
wp->w_dotp = bp->b_linep;
wp->w_doto = 0;
@@ -244,16 +211,15 @@ void edinit(char bname[])
* and arranges to move it to the "lastflag", so that the next command can
* look at it. Return the status of command.
*/
int execute(int c, int f, int n)
int
execute(int c, int f, int n)
{
KEYTAB *ktp;
int status;
ktp = &keytab[0]; /* Look in key table */
while (ktp->k_fp != NULL)
{
if (ktp->k_code == c)
{
while (ktp->k_fp != NULL) {
if (ktp->k_code == c) {
thisflag = 0;
status = (*ktp->k_fp) (f, n);
lastflag = thisflag;
@@ -263,10 +229,8 @@ int execute(int c, int f, int n)
}
if ((c >= 0x20 && c <= 0x7E) /* Self inserting */
|| (c >= 0xA0 && c <= 0xFE))
{
if (n <= 0)
{ /* Fenceposts */
|| (c >= 0xA0 && c <= 0xFE)) {
if (n <= 0) { /* Fenceposts */
lastflag = 0;
return (n < 0 ? FALSE : TRUE);
}
@@ -286,15 +250,15 @@ int execute(int c, int f, int n)
* Read in a key. Do the standard keyboard preprocessing. Convert the keys to
* the internal character set.
*/
int getkey()
int
getkey(void)
{
int c;
c = (*term.t_getchar) ();
if (c == METACH)
{ /* Apply M- prefix */
c = getctl ();
if (c == METACH) { /* Apply M- prefix */
c = getctl();
return (META | c);
}
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
@@ -305,11 +269,12 @@ int getkey()
/*
* Get a key. Apply control modifications to the read key.
*/
int getctl()
int
getctl()
{
int c;
c = (*term.t_getchar) ();
c = (*term.t_getchar)();
if (c >= 'a' && c <= 'z') /* Force to upper */
c -= 0x20;
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
@@ -317,43 +282,20 @@ int getctl()
return (c);
}
/*
* Fancy quit command, as implemented by Norm. If any buffer has changed
* do a write on that buffer and exit emacs, otherwise simply exit.
*/
int quickexit(int f, int n)
{
BUFFER *bp; /* scanning pointer to buffers */
bp = bheadp;
while (bp != NULL)
{
if ((bp->b_flag & BFCHG) != 0 /* Changed */
&& (bp->b_flag & BFTEMP) == 0)
{ /* Real */
curbp = bp; /* make that buffer current */
mlwrite("[Saving %s]", (int*)bp->b_fname);
filesave(f, n);
}
bp = bp->b_bufp; /* on to the next buffer */
}
return quit(f, n); /* conditionally quit */
}
/*
* Quit command. If an argument, always quit. Otherwise confirm if a buffer
* has been changed and not written out. Normally bound to "C-X C-C".
*/
int quit(int f, int n)
int
quit(int f, int n)
{
int s;
if (f != FALSE /* Argument forces it */
|| anycb () == FALSE /* All buffers clean */
|| (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE)
{
|| anycb() == FALSE /* All buffers clean */
|| (s = mlyesno("Quit without saving")) == TRUE) {
vttidy();
exit (0);
exit(0);
}
mlwrite("");
return (s);
@@ -363,10 +305,10 @@ int quit(int f, int n)
* Begin a keyboard macro. Error if not at the top level in keyboard
* processing. Set up variables and return.
*/
int ctlxlp(int f, int n)
int
ctlxlp(int f, int n)
{
if (kbdmip != NULL || kbdmop != NULL)
{
if (kbdmip != NULL || kbdmop != NULL) {
mlwrite("Not now");
return (FALSE);
}
@@ -379,10 +321,10 @@ int ctlxlp(int f, int n)
* End keyboard macro. Check for the same limit conditions as the above
* routine. Set up the variables and return to the caller.
*/
int ctlxrp(int f, int n)
int
ctlxrp(int f, int n)
{
if (kbdmip == NULL)
{
if (kbdmip == NULL) {
mlwrite("Not now");
return (FALSE);
}
@@ -395,36 +337,31 @@ int ctlxrp(int f, int n)
* Execute a macro. The command argument is the number of times to loop. Quit
* as soon as a command gets an error. Return TRUE if all ok, else FALSE.
*/
int ctlxe(int f, int n)
int
ctlxe(int f, int n)
{
int c, af, an, s;
if (kbdmip != NULL || kbdmop != NULL)
{
if (kbdmip != NULL || kbdmop != NULL) {
mlwrite("No macro defined");
return (FALSE);
}
if (n <= 0)
return (TRUE);
do
{
do {
kbdmop = &kbdm[0];
do
{
do {
af = FALSE;
an = 1;
if ((c = *kbdmop++) == (CTRL | 'U'))
{
if ((c = *kbdmop++) == (CTRL | 'U')) {
af = TRUE;
an = *kbdmop++;
c = *kbdmop++;
}
s = TRUE;
}
while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
} while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
kbdmop = NULL;
}
while (s == TRUE && --n);
} while (s == TRUE && --n);
return (s);
}
@@ -432,11 +369,11 @@ int ctlxe(int f, int n)
* Abort. Beep the beeper. Kill off any keyboard macro, etc., that is in
* progress. Sometimes called as a routine, to do general aborting of stuff.
*/
int ctrlg(int f, int n)
int
ctrlg(int f, int n)
{
(*term.t_beep) ();
if (kbdmip != NULL)
{
if (kbdmip != NULL) {
kbdm[0] = (CTLX | ')');
kbdmip = NULL;
}
@@ -444,33 +381,6 @@ int ctrlg(int f, int n)
return (ABORT);
}
/*
* Handle ANSI escape-extended commands (with "ESC [" or "ESC O" prefix)
*/
int extendedcmd(int f, int n)
{
int (*cmd)();
int c;
c = getctl();
switch (c)
{
case 'A': cmd = backline; break;
case 'B': cmd = forwline; break;
case 'C': cmd = forwchar; break;
case 'D': cmd = backchar; break;
case 'H': cmd = gotobob; break;
case 'W': cmd = gotoeob; break;
case '5': cmd = pageup; getctl(); break;
case '6': cmd = pagedown; getctl(); break;
case '7': cmd = gotobob; getctl(); break;
case '8': cmd = gotoeob; getctl(); break;
default: mlwrite("\007[Key not bound]");
return (FALSE);
}
return cmd(f, n);
}
/*
* Display the version. All this does
* is copy the version string into the echo line.
@@ -480,6 +390,6 @@ int extendedcmd(int f, int n)
int
showversion(int f, int n)
{
mlwrite("emg 1.8");
mlwrite("emg 2.0");
return (TRUE);
}

View File

@@ -9,25 +9,25 @@
#include "edef.h"
extern void mlwrite();
extern void lchange(int flag);
extern void lchange(int);
extern int lnewline();
extern int linsert(int n, int c);
extern int backchar(int f, int n);
extern int linsert(int, int);
extern int backchar(int, int);
extern void kdelete();
extern int ldelete(int f, int n);
extern int kremove(int k);
extern int ldelete(int, int);
extern int kremove(int);
int setfillcol(int f, int n);
int getccol(int bflg);
int twiddle(int f, int n);
int quote(int f, int n);
int tab(int f, int n);
int openline(int f, int n);
int newline(int f, int n);
int forwdel(int f, int n);
int backdel(int f, int n);
int killtext(int f, int n);
int yank(int f, int n);
int setfillcol(int, int);
int getccol(int);
int twiddle(int, int);
int quote(int, int);
int tab(int, int);
int openline(int, int);
int newline(int, int);
int forwdel(int, int);
int backdel(int, int);
int killtext(int, int);
int yank(int, int);
/*
* Set fill column to n.

View File

@@ -10,13 +10,13 @@
#include "edef.h"
extern void kdelete();
extern int ldelete(int f, int n);
extern int kinsert(int c);
extern int ldelete(int, int);
extern int kinsert(int);
extern void mlwrite();
int killregion(int f, int n);
int copyregion(int f, int n);
int getregion(REGION *rp);
int killregion(int, int);
int copyregion(int, int);
int getregion(REGION *);
/*
* Kill the region. Ask "getregion" to figure out the bounds of the region.

View File

@@ -11,21 +11,21 @@
#include "edef.h"
extern void mlwrite();
extern int mlreplyt(char *prompt, char *buf, int nbuf, char eolchar);
extern int mlreplyt(char *, char *, int, char);
extern void update();
extern int forwchar(int f, int n);
extern int ldelete(int n, int kflag);
extern int linsert(int n, int c);
extern int forwchar(int, int);
extern int ldelete(int, int);
extern int linsert(int, int);
int forwsearch(int f, int n);
int forwhunt(int f, int n);
int backsearch(int f, int n);
int backhunt(int f, int n);
int bsearch(int f, int n);
int eq(int bc, int pc);
int readpattern(char *prompt);
int forscan(char *patrn, int leavep);
void expandp(char *srcstr, char *deststr, int maxlength);
int forwsearch(int, int);
int forwhunt(int, int);
int backsearch(int, int);
int backhunt(int, int);
int bsearch(int, int);
int eq(int, int);
int readpattern(char *);
int forscan(char *, int);
void expandp(char *, char *, int);
#define PTBEG 1 /* leave the point at the begining on search */
#define PTEND 2 /* leave the point at the end on search */

View File

@@ -2,9 +2,8 @@
/* termios video driver */
#define termdef 1 /* don't define "term" externally */
#include <stdio.h> /* puts(3), snprintf(3) */
#include "estruct.h"
#include "edef.h"
#undef CTRL /* Needs to be done here. */
@@ -22,15 +21,15 @@ extern void ttputc();
extern void ttflush();
extern void ttclose();
extern void panic();
extern void panic(char *);
void getwinsize();
void tcapopen();
void tcapmove(int row, int col);
void tcapeeol();
void tcapeeop();
void tcaprev();
void tcapbeep();
void getwinsize(void);
void tcapopen(void);
void tcapmove(int, int);
void tcapeeol(void);
void tcapeeop(void);
void tcaprev(int);
void tcapbeep(void);
#define MARGIN 8
#define SCRSIZ 64
@@ -45,25 +44,27 @@ TERM term = {
ttflush, tcapmove, tcapeeol, tcapeeop, tcapbeep, tcaprev
};
void getwinsize()
void
getwinsize(void)
{
int cols = COLS;
int rows = ROWS;
struct winsize ws;
/* Too small and we're out */
if ((cols < 10) || (rows < 3))
panic("Too few columns or rows");
if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
term.t_ncol = ws.ws_col;
rows = ws.ws_row;
}
if (COLS > MAXCOL)
cols = MAXCOL;
if (ROWS > MAXROW)
rows = MAXROW;
/* Too small and we hard code */
if ((term.t_ncol < 10) || (rows < 3)) {
term.t_ncol = 80;
rows = 24;
}
term.t_ncol = cols;
term.t_nrow = rows - 1;
}
void tcapopen()
void
tcapopen(void)
{
char tcbuf[1024];
char *p, *tv_stype;
@@ -87,31 +88,36 @@ void tcapopen()
panic("Need cl & cm abilities");
if (p >= &tcapbuf[TCAPSLEN]) /* XXX */
panic("Description too big");
ttopen ();
ttopen();
}
void tcaprev(int state)
void
tcaprev(int state)
{
if (revexist)
tputs((state ? SO : SE), 1, ttputc);
}
void tcapmove (int row, int col)
void
tcapmove(int row, int col)
{
tputs(tgoto(CM, col, row), 1, ttputc);
}
void tcapeeol()
void
tcapeeol(void)
{
tputs(CE, 1, ttputc);
}
void tcapeeop()
void
tcapeeop(void)
{
tputs(CL, 1, ttputc);
}
void tcapbeep()
void
tcapbeep(void)
{
ttputc(BEL);
}

View File

@@ -9,11 +9,11 @@
#include "estruct.h"
#include "edef.h"
extern int backchar(int f, int n);
extern int forwchar(int f, int n);
extern int backchar(int, int);
extern int forwchar(int, int);
int backword(int f, int n);
int forwword(int f, int n);
int backword(int, int);
int forwword(int, int);
int inword(void);
/*
@@ -21,14 +21,14 @@ int inword(void);
* performed by the "backchar" and "forwchar" routines. Error if you try to
* move beyond the buffers
*/
int backword(int f, int n)
int
backword(int f, int n)
{
if (n < 0)
return (forwword(f, -n));
if (backchar(FALSE, 1) == FALSE)
return (FALSE);
while (n--)
{
while (n--) {
while (inword() == FALSE)
{
if (backchar(FALSE, 1) == FALSE)
@@ -47,12 +47,12 @@ int backword(int f, int n)
* Move the cursor forward by the specified number of words. All of the motion
* is done by "forwchar". Error if you try and move beyond the buffer's end
*/
int forwword(int f, int n)
int
forwword(int f, int n)
{
if (n < 0)
return (backword(f, -n));
while (n--)
{
while (n--) {
while (inword() != FALSE)
{
if (forwchar(FALSE, 1) == FALSE)
@@ -71,7 +71,8 @@ int forwword(int f, int n)
* Return TRUE if the character at dot is a character that is considered to be
* part of a word. The word character list is hard coded. Should be setable
*/
int inword(void)
int
inword(void)
{
int c;

View File

@@ -1568,7 +1568,8 @@ int main (argc, argv)
if (! ofilfnd) {
unlink ("a.out");
link ("l.out", "a.out");
if (link ("l.out", "a.out") < 0)
perror("a.out");
ofilename = "a.out";
}
delarg = errlev;

View File

@@ -262,7 +262,7 @@ bad1: (void)lseek(rfd, (off_t)r_off, SEEK_SET);
void symobj()
{
register RLIB *rp;
char hb[sizeof(struct ar_hdr) + 1];
char hb[sizeof(struct ar_hdr) + 1 + 64];
long ransize, baseoff;
/* Rewind the archive, leaving the magic number. */
@@ -385,7 +385,8 @@ int build()
(void)lseek(tfd, (off_t)0, SEEK_SET);
SETCF(tfd, tname, afd, archive, RPAD|WPAD);
copy_ar(&cf, size);
(void)ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR));
if (ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR)) < 0)
/* ignore */;
(void)close(tfd);
/* Set the time. */

View File

@@ -32,5 +32,5 @@ install: smlrc
clean:
rm -f *.o smlrc smlrc.dis smlrc.elf
###
smlrc.o: smlrc.c cgmips.c
smlrc.o: smlrc.c fp.c cgmips.c
${CC} ${CFLAGS} -mips16 smlrc.c -c -o $@

View File

@@ -546,6 +546,11 @@ void GenFxnProlog(void)
int i, cnt = CurFxnParamCntMax;
if (cnt > 4)
cnt = 4;
// TBD!!! for structure passing use the cumulative parameter size
// instead of the number of parameters. Currently this bug is masked
// by the subroutine that pushes structures on the stack (it copies
// all words except the first to the stack). But passing structures
// in registers from assembly code won't always work.
for (i = 0; i < cnt; i++)
GenPrintInstr2Operands(MipsInstrSW, 0,
MipsOpRegA0 + i, 0,

323
src/cmd/smlrc/fp.c Normal file
View 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;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2015, Alexey Frunze
Copyright (c) 2013-2016, Alexey Frunze
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -66,6 +66,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern int main(int argc, char** argv);
void exit(int);
#ifdef __SMALLER_C_32__
extern void __x87init(void);
#endif
#ifdef _RETROBSD
void __start__(int argc, char** argv)
{
@@ -75,6 +79,7 @@ void __start__(int argc, char** argv)
#ifdef _LINUX
void __start__(int argc, char** argv)
{
__x87init();
exit(main(argc, argv));
}
#else
@@ -85,6 +90,9 @@ void __start__(void)
int argc;
char** argv;
__setargs__(&argc, &argv);
#ifdef __SMALLER_C_32__
__x87init();
#endif
exit(main(argc, argv));
}
#endif
@@ -371,6 +379,22 @@ void* memset(void* s, int c, unsigned n)
return s;
}
#ifdef __SMALLER_C_32__
int memcmp(void* s1, void* s2, unsigned n)
{
if (n)
{
unsigned char *p1 = s1, *p2 = s2;
do
{
if (*p1++ != *p2++)
return (*--p1 - *--p2);
} while (--n);
}
return 0;
}
#endif
int fputc(int c, FILE* stream);
int putchar(int c);
@@ -1548,4 +1572,187 @@ int fsetpos(FILE* stream, fpos_t* pos)
return 0;
}
#ifdef __SMALLER_C_32__
#ifndef _RETROBSD
#ifdef __HUGE__
#define xbp "bp"
#define xsp "sp"
#else
#define xbp "ebp"
#define xsp "esp"
#endif
void __x87init(void)
{
// Mask all exceptions, set rounding to nearest even and precision to 64 bits.
// TBD??? Actually check for x87???
asm("fninit");
}
float __floatsisf(int i)
{
asm
(
"fild dword ["xbp"+8]\n"
"fstp dword ["xbp"+8]\n"
"mov eax, ["xbp"+8]"
);
}
float __floatunsisf(unsigned i)
{
asm
(
"push dword 0\n"
"push dword ["xbp"+8]\n"
"fild qword ["xbp"-8]\n" // load 32-bit unsigned int as 64-bit signed int
"add "xsp", 8\n"
"fstp dword ["xbp"+8]\n"
"mov eax, ["xbp"+8]"
);
}
int __fixsfsi(float f)
{
asm
(
"sub "xsp", 4\n"
"fnstcw ["xbp"-2]\n" // save rounding
"mov ax, ["xbp"-2]\n"
"mov ah, 0x0c\n" // rounding towards 0 (AKA truncate) since we don't have fisttp
"mov ["xbp"-4], ax\n"
"fld dword ["xbp"+8]\n"
"fldcw ["xbp"-4]\n" // rounding = truncation
"fistp dword ["xbp"+8]\n"
"fldcw ["xbp"-2]\n" // restore rounding
"add "xsp", 4\n"
"mov eax, ["xbp"+8]"
);
}
unsigned __fixunssfsi(float f)
{
asm
(
"sub "xsp", 12\n"
"fnstcw ["xbp"-2]\n" // save rounding
"mov ax, ["xbp"-2]\n"
"mov ah, 0x0c\n" // rounding towards 0 (AKA truncate) since we don't have fisttp
"mov ["xbp"-4], ax\n"
"fld dword ["xbp"+8]\n"
"fldcw ["xbp"-4]\n" // rounding = truncation
"fistp qword ["xbp"-12]\n" // store 64-bit signed int
"fldcw ["xbp"-2]\n" // restore rounding
"mov eax, ["xbp"-12]\n" // take low 32 bits
"add "xsp", 12"
);
}
float __addsf3(float a, float b)
{
asm
(
"fld dword ["xbp"+8]\n"
"fadd dword ["xbp"+12]\n"
"fstp dword ["xbp"+8]\n"
"mov eax, ["xbp"+8]"
);
}
float __subsf3(float a, float b)
{
asm
(
"fld dword ["xbp"+8]\n"
"fsub dword ["xbp"+12]\n"
"fstp dword ["xbp"+8]\n"
"mov eax, ["xbp"+8]"
);
}
float __negsf2(float f)
{
asm
(
"mov eax, ["xbp"+8]\n"
"xor eax, 0x80000000"
);
}
float __mulsf3(float a, float b)
{
asm
(
"fld dword ["xbp"+8]\n"
"fmul dword ["xbp"+12]\n"
"fstp dword ["xbp"+8]\n"
"mov eax, ["xbp"+8]"
);
}
float __divsf3(float a, float b)
{
asm
(
"fld dword ["xbp"+8]\n"
"fdiv dword ["xbp"+12]\n"
"fstp dword ["xbp"+8]\n"
"mov eax, ["xbp"+8]"
);
}
float __lesf2(float a, float b)
{
asm
(
"fld dword ["xbp"+12]\n"
"fld dword ["xbp"+8]\n"
"fucompp\n"
"fstsw ax\n" // must use these moves since we don't have fucomip
"sahf\n"
"jnp .ordered\n"
"mov eax, +1\n" // return +1 if either a or b (or both) is a NaN
"jmp .done\n"
".ordered:\n"
"jnz .unequal\n"
"xor eax, eax\n" // return 0 if a == b
"jmp .done\n"
".unequal:\n"
"sbb eax, eax\n"
"jc .done\n" // return -1 if a < b
"inc eax\n" // return +1 if a > b
".done:"
);
}
float __gesf2(float a, float b)
{
asm
(
"fld dword ["xbp"+12]\n"
"fld dword ["xbp"+8]\n"
"fucompp\n"
"fstsw ax\n" // must use these moves since we don't have fucomip
"sahf\n"
"jnp .ordered\n"
"mov eax, -1\n" // return -1 if either a or b (or both) is a NaN
"jmp .done\n"
".ordered:\n"
"jnz .unequal\n"
"xor eax, eax\n" // return 0 if a == b
"jmp .done\n"
".unequal:\n"
"sbb eax, eax\n"
"jc .done\n" // return -1 if a < b
"inc eax\n" // return +1 if a > b
".done:"
);
}
#endif
#endif
#endif /*__APPLE__*/

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
#include <fcntl.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/termios.h>
#include <termios.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>

View File

@@ -50,7 +50,8 @@ strip(name)
head.a_reldata = 0;
head.a_syms = 0;
(void) lseek(f, (off_t)0, SEEK_SET);
(void) write(f, (char *)&head, sizeof (head));
if (write(f, (char *)&head, sizeof (head)) != sizeof (head))
/* ignore */;
out:
close(f);
}

View File

@@ -57,7 +57,7 @@ OPTON = -O2 -fomit-frame-pointer -fforce-addr -ffast-math -Wall
#CFLAGS = -DTIME -std1 -verbose -w0
## generic gcc CFLAGS. -DTIME must be included
CFLAGS = -DTIME -Wall -pedantic -ansi
#CFLAGS = -DTIME -Wall -pedantic -ansi
# local directories
PROGDIR = ./pgms

View File

@@ -67,7 +67,6 @@ char *vi_Version =
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/time.h>
@@ -81,12 +80,17 @@ char *vi_Version =
#include <ctype.h>
#include <assert.h>
#include <errno.h>
//#include <err.h>
#include <stdarg.h>
#include "lib/last_char_is.c"
#include "lib/strlcat.c"
#include "lib/strlcpy.c"
#if defined(linux) || defined(__APPLE__)
# include <termios.h>
# include <err.h>
#else
# include "lib/strlcat.c"
# include "lib/strlcpy.c"
# define termios sgttyb
#endif
#include <strings.h>
@@ -96,7 +100,6 @@ char *vi_Version =
#endif /* TRUE */
#define MAX_SCR_COLS BUFSIZ
#define BUFSIZ_STATBUF 200
#define termios sgttyb
// Misc. non-Ascii keys that report an escape sequence
#define VI_K_UP 128 // cursor key Up
@@ -1789,7 +1792,8 @@ static void colon(Byte * buf)
while (isblnk(*buf))
buf++;
/* FIXED strcpy((char *) args, (char *) buf); */
if (strlcpy((char *) args, (char *) buf, sizeof((char *)args)) > sizeof((char *)args)) err(1, "strlcpy overflow in function colon");
if (strlcpy((char *) args, (char *) buf, sizeof(args)) > sizeof(args))
err(1, "strlcpy overflow in function colon");
buf1 = (Byte *)last_char_is((char *)cmd, '!');
if (buf1) {
useforce = TRUE;
@@ -3183,7 +3187,7 @@ static int isblnk(Byte c) // is the char a blank or tab
//----- Set terminal attributes --------------------------------
static void rawmode(void)
{
#if 0
#ifdef TCSANOW
tcgetattr(0, &term_orig);
term_vi = term_orig;
term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG ON- allow intr's
@@ -3208,7 +3212,7 @@ static void rawmode(void)
static void cookmode(void)
{
#if 0
#ifdef TCSANOW
tcsetattr(0, TCSANOW, &term_orig);
#else
ioctl(0, TIOCSETP, &term_orig);

1
src/cmd/yacc/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
yacc

View File

@@ -1,24 +1,31 @@
#
# @(#)Makefile 4.2.1 (2.11BSD) 1996/10/24
#
DESTDIR=
SEPFLAG= -i
CFLAGS=-O
SRCS = Makefile dextern files yaccpar \
y1.c y2.c y3.c y4.c \
yaccdiffs yaccnews
#==========================================
# Makefile: makefile for yacc
# Copyright 2012 Majenko Technolohies
# (matt@majenko.co.uk
# Last Modified: 29/01/2012
#==========================================
TOPSRC = $(shell cd ../../..; pwd)
include $(TOPSRC)/target.mk
OBJS = y1.o y2.o y3.o y4.o
SRCS = y1.c y2.c y3.c y4.c
all: yacc
yacc: y1.o y2.o y3.o y4.o
$(CC) ${SEPFLAG} -o yacc y?.o
y1.o y2.o y3.o y4.o: dextern files
install: yacc yaccpar
install -s yacc $(DESTDIR)/usr/bin
install -c yaccpar $(DESTDIR)/usr/share/misc
clean :
-rm -f *.o yacc
yacc: ${OBJS}
${CC} ${LDFLAGS} -o yacc.elf ${OBJS} ${LIBS}
${OBJDUMP} -S yacc.elf > yacc.dis
${SIZE} yacc.elf
${ELF2AOUT} yacc.elf $@
srcs: $(SRCS)
$(SRCS):
sccs get $@
clean:
-rm -f yacc ${OBJS} yacc.elf yacc.dis
install: all
install yacc $(DESTDIR)/bin/
y1.o: y1.c dextern
y2.o: y2.c dextern
y3.o: y3.c dextern
y4.o: y4.c dextern

View File

@@ -33,7 +33,7 @@
# ifdef MEDIUM
# define ACTSIZE 4000
# define MEMSIZE 5200
# define NSTATES 600
# define NSTATES 750
# define NTERMS 127
# define NPROD 400
# define NNONTERM 200
@@ -43,6 +43,19 @@
# define WSETSIZE 250
# endif
# ifdef TINY
# define ACTSIZE 1000
# define MEMSIZE 1300
# define NSTATES 750
# define NTERMS 127
# define NPROD 200
# define NNONTERM 50
# define TEMPSIZE 200
# define CNAMSZ 1000
# define LSETSIZE 250
# define WSETSIZE 100
# endif
# define NAMESIZE 50
# define NTYPES 63

View File

@@ -17,4 +17,5 @@
/* basic size of the Yacc implementation */
/* # define HUGE */
#define MEDIUM
/* #define MEDIUM */
#define TINY

View File

@@ -3,6 +3,7 @@ static char sccsid[] = "@(#)y1.c 4.1.1 (2.11BSD) 1995/05/11";
#endif
# include "dextern"
#include <stdlib.h>
/* variables used locally */

View File

@@ -3,18 +3,19 @@
*/
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
"elf32-littlemips")
OUTPUT_ARCH(mips)
OUTPUT_ARCH(pic32mx)
ENTRY(_start)
/* Required by Microchip C32 linker */
/*MEMORY
MEMORY
{
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x80000
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 512K
exception_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x1000
kseg0_boot_mem (rx) : ORIGIN = 0x9FC00000, LENGTH = 12K-16
kseg1_boot_mem (rx) : ORIGIN = 0xBFC00000, LENGTH = 0x490
kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x20000
}*/
}
_min_heap_size = 0;
SECTIONS
{

View File

@@ -1,3 +1,4 @@
aclock
arithmetic
banner
bcd

View File

@@ -18,7 +18,7 @@ SUBDIR = adventure atc backgammon battlestar boggle btlgammon \
# C programs that live in the current directory and do not need
# explicit make lines.
#
STD = banner arithmetic bcd cfscores factor fish morse \
STD = banner aclock arithmetic bcd cfscores factor fish morse \
number ppt wump
# C programs that live in the current directory and need explicit make lines.

175
src/games/aclock.c Normal file
View 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;
}

View File

@@ -9,7 +9,7 @@ TOPSRC = $(shell cd ../../..; pwd)
include $(TOPSRC)/target.mk
#include $(TOPSRC)/cross.mk
CFLAGS = -Os -g -Werror -Wall
CFLAGS += -Os -g -Werror -Wall
CFLAGS += -DBSD -DDEST=\"/games/lib/atc/\"
#CFLAGS += -DSYSV -DDEST=\"games/\"
YFLAGS = -d

View File

@@ -4,16 +4,27 @@
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#include <float.h>
#include <math.h>
#include <ctype.h>
/*
* BIG = 2**(DBL_MANT_DIG+3) defines how many decimal digits
* to take into account from the input. It doesn't make sense
* to use more digits than log10(2**DBL_MANT_DIG)+1.
* BIG is equal 2**27 or 2**56, depending on whether double
* is single or double precision.
*/
#define BIG (8 * (double)(1L << (DBL_MANT_DIG/2)) * \
(double)(1L << (DBL_MANT_DIG/2 + DBL_MANT_DIG%2)))
double
atof(p)
register char *p;
{
register int c;
double fl, flexp, exp5;
double big = 72057594037927936.; /*2^56*/
double big = BIG;
int nd;
register int eexp, exp, neg, negexp, bexp;
@@ -73,7 +84,7 @@ register char *p;
}
if ((nd+exp*negexp) < -LOGHUGE){
if ((nd+exp*negexp) < DBL_MIN_10_EXP - 2) {
fl = 0;
exp = 0;
}

View File

@@ -1,3 +1,4 @@
#include <float.h>
#include <math.h>
double
@@ -5,10 +6,11 @@ ldexp(fr, exp)
double fr;
int exp;
{
double huge = 1.701411834604692293e38;
int neg;
int i;
if (fr == 0)
return 0;
neg = 0;
if (fr < 0) {
fr = -fr;
@@ -20,13 +22,13 @@ ldexp(fr, exp)
i = i-1;
}
exp = exp+i;
if (exp > 127) {
if (exp >= DBL_MAX_EXP) {
if (neg)
return(-huge);
return(-HUGE_VAL);
else
return(huge);
return(HUGE_VAL);
}
if (exp < -127)
if (exp < DBL_MIN_EXP - 2)
return(0);
while (exp > 30) {
fr = fr*(1L<<30);

View File

@@ -20,7 +20,8 @@ include $(TOPSRC)/target.mk
CFLAGS += ${DEFS}
OBJS = addsf3.o comparesf2.o divsf3.o fixsfsi.o floatsisf.o \
mulsf3.o negsf2.o subsf3.o sc_case.o
mulsf3.o negsf2.o subsf3.o sc_case.o fixunssfsi.o \
floatunsisf.o
all: ${OBJS}

View 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;
}

View File

@@ -16,8 +16,6 @@
#define SINGLE_PRECISION
#include "fp_lib.h"
//#include "int_lib.h"
fp_t
__floatsisf(int a)
{

View 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);
}

View File

@@ -41,8 +41,10 @@
#include <float.h>
#include <math.h>
/* Max number conversion buffer length: a long in base 2, plus NUL byte. */
#define MAXNBUF (sizeof(long) * 8 + 1)
/* Max number conversion buffer length. */
#define MAXNBUF \
(1/*sign*/ + DBL_MAX_10_EXP+1/*max integral digits*/ + \
1/*.*/ + DBL_DIG+1/*max fractional digits*/ + 1/*NUL*/)
static unsigned char *ksprintn (unsigned char *buf, unsigned long v, unsigned char base,
int width, unsigned char *lp);
@@ -169,21 +171,11 @@ reswitch: switch (c = *fmt++) {
break;
case 'D':
s = va_arg (ap, const unsigned char*);
if (! width)
width = 16;
if (sharpflag)
padding = ':';
while (width--) {
c = *s++;
PUTC (mkhex (c >> 4));
PUTC (mkhex (c));
if (width)
PUTC (padding);
}
break;
lflag=1;
/* FALLTHROUGH */
case 'd':
case 'i':
ul = lflag ? va_arg (ap, long) : va_arg (ap, int);
if (! sign) sign = 1;
base = 10;
@@ -209,7 +201,7 @@ reswitch: switch (c = *fmt++) {
sharpflag = (width == 0);
goto nosign;
case 'n':
case 'n': /* TBD!!! fix this non-standard %n */
ul = lflag ? va_arg (ap, unsigned long) :
sign ? (unsigned long) va_arg (ap, int) :
va_arg (ap, unsigned int);
@@ -292,7 +284,7 @@ cnt_unknown: if (ladjust)
goto number;
nosign: sign = 0;
number: if (sign && ((long) ul != 0L)) {
number: if (sign) {
if ((long) ul < 0L) {
neg = '-';
ul = -(long) ul;
@@ -403,7 +395,7 @@ number: if (sign && ((long) ul != 0L)) {
nbuf [size + 1] = 0;
}
}
if (neg)
if (neg || sign)
size++;
if (! ladjust && width && padding == ' ' &&
(width -= size) > 0)
@@ -411,8 +403,11 @@ number: if (sign && ((long) ul != 0L)) {
PUTC (' ');
} while (--width > 0);
if (neg)
if (neg) {
PUTC ('-');
} else if (sign) {
PUTC ('+');
}
if (! ladjust && width && (width -= size) > 0)
do {

View File

@@ -5,8 +5,8 @@ CFLAGS += -O -Wall -Werror
MAN = gpanel.0
MANSRC = gpanel.3
OBJS = open.o clear.o pixel.o line.o rect.o fill.o circle.o \
image.o char.o text.o text_width.o
OBJS = open.o clear.o pixel.o line.o rect.o fill.o fill_triangle.o \
circle.o image.o char.o text.o text_width.o
all: ../libgpanel.a $(MAN)

View 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);
}
}

View File

@@ -4,6 +4,7 @@
*
* The coefficients are #1069 from Hart and Cheney. (22.35D)
*/
#include <float.h>
#include <errno.h>
#include <math.h>
@@ -16,7 +17,7 @@ static double q1 = .3277251518082914423057964422e6;
static double q2 = .1749287689093076403844945335e4;
static double log2e = 1.4426950408889634073599247;
static double sqrt2 = 1.4142135623730950488016887;
static double maxf = 10000;
static double maxf = DBL_MAX_10_EXP * 2.5/*>ln(10)*/;
double
exp(arg)
@@ -32,7 +33,7 @@ double arg;
return(0.);
if(arg > maxf) {
errno = ERANGE;
return(HUGE);
return(HUGE_VAL);
}
arg *= log2e;
ent = floor(arg);

View File

@@ -1,111 +1,268 @@
#include <stdio.h>
#include <stdint.h>
#include "ieee.h"
typedef union {
double value;
struct {
uint32_t lo;
uint32_t hi;
} uns;
} union64_t;
/*
* Get two 32 bit ints from a double.
*/
#define UNPACK_DOUBLE(high,low,d) {\
union64_t u = {0}; \
u.value = d; \
high = u.uns.hi; \
low = u.uns.lo; \
}
/*
* Set a double from two 32 bit ints.
*/
#define PACK_DOUBLE(d,high,low) { \
union64_t u = {0}; \
u.uns.hi = high; \
u.uns.lo = low; \
d = u.value; \
}
typedef union {
float value;
uint32_t word;
} union32_t;
/*
* Get two 32 bit ints from a double.
*/
#define UNPACK_FLOAT(w,f) {\
union32_t u = {0}; \
u.value = f; \
w = u.word; \
}
/*
* Set a double from two 32 bit ints.
*/
#define PACK_FLOAT(f,w) { \
union32_t u = {0}; \
u.word = w; \
f = u.value; \
}
static const double one = 1.0, Zero[] = {0.0, -0.0,};
double fmod(double x, double y)
{
int32_t n=0,hx=0,hy=0,hz=0,ix=0,iy=0,sx=0,i=0;
uint32_t lx=0,ly=0,lz=0;
int32_t n=0, hx=0, hy=0, hz=0, ix=0, iy=0, sx=0, i=0;
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hy,ly,y);
sx = hx&0x80000000; /* sign of x */
hx ^=sx; /* |x| */
if (sizeof(float) == sizeof(double)) {
/*
* Double is 32-bit.
*/
UNPACK_FLOAT(hx,x);
UNPACK_FLOAT(hy,y);
sx = hx & 0x80000000; /* sign of x */
hx ^= sx; /* |x| */
hy &= 0x7fffffff; /* |y| */
/* purge off exception values */
if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
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*/
if (hy == 0 || hx >= 0x7f800000 || /* y=0, or x not finite */
hy > 0x7f800000) /* or y is NaN */
return (x*y) / (x*y);
if (hx < hy)
return x; /* |x| < |y| return x */
if (hx == hy)
return Zero[(uint32_t)sx >> 31]; /* |x| = |y| return x*0*/
/* determine ix = ilogb(x) */
if (hx < 0x00800000) { /* subnormal x */
for (ix= -126, i=hx<<8; i>0; i<<=1)
ix -= 1;
} else
ix = (hx >> 23) - 127;
/* determine iy = ilogb(y) */
if (hy < 0x00800000) { /* subnormal y */
for (iy= -126, i=hy<<8; i>=0; i<<=1)
iy -= 1;
} else iy = (hy >> 23) - 127;
/* set up {hx,lx}, {hy,ly} and align y to x */
if (ix >= -126)
hx = 0x00800000 | (0x007fffff & hx);
else { /* subnormal x, shift x to normal */
n = -126 - ix;
hx = hx << n;
}
if (iy >= -126)
hy = 0x00800000 | (0x007fffff & hy);
else { /* subnormal y, shift y to normal */
n = -126 - iy;
hy = hy << n;
}
/* fix point fmod */
n = ix - iy;
while (n--) {
hz = hx - hy;
if (hz < 0) {
hx = hx + hx;
} else {
if (hz == 0) /* return sign(x)*0 */
return Zero[(uint32_t)sx >> 31];
hx = hz + hz;
}
}
hz = hx - hy;
if (hz >= 0) {
hx = hz;
}
/* convert back to floating value and restore the sign */
if (hx == 0) /* return sign(x)*0 */
return Zero[(uint32_t)sx >> 31];
while (hx < 0x00800000) { /* normalize x */
hx = hx + hx;
iy -= 1;
}
if (iy >= -126) { /* normalize output */
hx = (hx - 0x00800000) | ((iy + 127) << 23);
PACK_FLOAT(x, hx | sx);
} else { /* subnormal output */
n = -126 - iy;
hx >>= n;
PACK_FLOAT(x, hx | sx);
x *= one; /* create necessary signal */
}
} else {
/*
* Double is 64-bit.
*/
uint32_t lx=0, ly=0, lz=0;
UNPACK_DOUBLE(hx, lx, x);
UNPACK_DOUBLE(hy, ly, y);
sx = hx & 0x80000000; /* sign of x */
hx ^= sx; /* |x| */
hy &= 0x7fffffff; /* |y| */
/* purge off exception values */
if ((hy | ly) == 0 || hx >= 0x7ff00000 || /* y=0,or x not finite */
(hy | ((ly | -ly) >> 31)) > 0x7ff00000) /* or y is NaN */
return (x*y) / (x*y);
if (hx <= hy) {
if (hx < hy || lx < ly)
return x; /* |x| < |y| return x */
if (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;
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;
for (ix = -1022, i=hx<<11; i>0; i<<=1)
ix -= 1;
}
} else ix = (hx>>20)-1023;
} else
ix = (hx >> 20) - 1023;
/* determine iy = ilogb(y) */
if(hy<0x00100000) { /* subnormal y */
if (hy < 0x00100000) { /* subnormal y */
if(hy==0) {
for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
for (iy = -1043, i=ly; i>0; i<<=1)
iy -= 1;
} else {
for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
for (iy = -1022,i=(hy<<11); i>0; i<<=1)
iy -= 1;
}
} else iy = (hy>>20)-1023;
} else
iy = (hy >> 20) - 1023;
/* set up {hx,lx}, {hy,ly} and align y to x */
if(ix >= -1022)
hx = 0x00100000|(0x000fffff&hx);
if (ix >= -1022)
hx = 0x00100000 | (0x000fffff & hx);
else { /* subnormal x, shift x to normal */
n = -1022-ix;
if(n<=31) {
hx = (hx<<n)|(lx>>(32-n));
n = -1022 - ix;
if (n <= 31) {
hx = (hx << n) | (lx >> (32 - n));
lx <<= n;
} else {
hx = lx<<(n-32);
hx = lx << (n - 32);
lx = 0;
}
}
if(iy >= -1022)
hy = 0x00100000|(0x000fffff&hy);
if (iy >= -1022)
hy = 0x00100000 | (0x000fffff & hy);
else { /* subnormal y, shift y to normal */
n = -1022-iy;
if(n<=31) {
hy = (hy<<n)|(ly>>(32-n));
n = -1022 - iy;
if (n <= 31) {
hy = (hy << n) | (ly >> (32 - n));
ly <<= n;
} else {
hy = ly<<(n-32);
hy = ly << (n - 32);
ly = 0;
}
}
/* fix point fmod */
n = ix - iy;
while(n--) {
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
else {
if((hz|lz)==0) /* return sign(x)*0 */
return Zero[(uint32_t)sx>>31];
hx = hz+hz+(lz>>31); lx = lz+lz;
while (n--) {
hz = hx - hy;
lz = lx - ly;
if (lx < ly)
hz -= 1;
if (hz < 0) {
hx = hx + hx + (lx >> 31);
lx = lx + lx;
} else {
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;
if(hz>=0) {hx=hz;lx=lz;}
hz = hx - hy;
lz = lx - ly;
if (lx < ly)
hz -= 1;
if (hz >= 0) {
hx = hz;
lx = lz;
}
/* convert back to floating value and restore the sign */
if((hx|lx)==0) /* return sign(x)*0 */
return Zero[(uint32_t)sx>>31];
while(hx<0x00100000) { /* normalize x */
hx = hx+hx+(lx>>31); lx = lx+lx;
if ((hx | lx) == 0) /* return sign(x)*0 */
return Zero[(uint32_t)sx >> 31];
while (hx < 0x00100000) { /* normalize x */
hx = hx + hx + (lx >> 31);
lx = lx + lx;
iy -= 1;
}
if(iy>= -1022) { /* normalize output */
hx = ((hx-0x00100000)|((iy+1023)<<20));
INSERT_WORDS(x,hx|sx,lx);
if (iy >= -1022) { /* normalize output */
hx = (hx - 0x00100000) | ((iy + 1023) << 20);
PACK_DOUBLE(x, hx | sx, lx);
} else { /* subnormal output */
n = -1022 - iy;
if(n<=20) {
lx = (lx>>n)|((uint32_t)hx<<(32-n));
if (n <= 20) {
lx = (lx >> n) | ((uint32_t)hx << (32 - n));
hx >>= n;
} else if (n<=31) {
lx = (hx<<(32-n))|(lx>>n); hx = sx;
} else if (n <= 31) {
lx = (hx << (32 - n)) | (lx >> n);
hx = sx;
} else {
lx = hx>>(n-32); hx = sx;
lx = hx >> (n - 32);
hx = sx;
}
INSERT_WORDS(x,hx|sx,lx);
PACK_DOUBLE(x, hx | sx, lx);
x *= one; /* create necessary signal */
}
}
return x; /* exact output */
}

View File

@@ -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;

View File

@@ -176,7 +176,7 @@ y0(arg)
errno = 0;
if(arg <= 0.){
errno = EDOM;
return(-HUGE);
return(-HUGE_VAL);
}
if(arg > 8.){
asympt(arg);

View File

@@ -182,7 +182,7 @@ y1(arg)
x = arg;
if(x <= 0.){
errno = EDOM;
return(-HUGE);
return(-HUGE_VAL);
}
if(x > 8.){
asympt(x);

View File

@@ -82,7 +82,7 @@ yn(n,x) int n; double x;{
if (x <= 0) {
errno = EDOM;
return(-HUGE);
return(-HUGE_VAL);
}
sign = 1;
if(n<0){

View File

@@ -31,7 +31,7 @@ double arg;
if(arg <= 0.) {
errno = EDOM;
return(-HUGE);
return(-HUGE_VAL);
}
x = frexp(arg,&exp);
while(x<0.5) {

View File

@@ -64,8 +64,8 @@ tan(arg)
if(temp == 0.) {
errno = ERANGE;
if (sign>0)
return(HUGE);
return(-HUGE);
return(HUGE_VAL);
return(-HUGE_VAL);
}
temp = 1./temp;
}

View File

@@ -16,7 +16,7 @@
#endif /* !MAL */
char *
imalloc(n)
imalloc(int n)
{
#ifdef MAL
register char * result;
@@ -33,7 +33,7 @@ imalloc(n)
}
char *
icalloc(nelem, elsize)
icalloc(int nelem, int elsize)
{
if (nelem == 0 || elsize == 0)
nelem = elsize = 1;
@@ -41,8 +41,7 @@ icalloc(nelem, elsize)
}
char *
irealloc(pointer, size)
char * pointer;
irealloc(char *pointer, int size)
{
if (NULLMAL(pointer))
return imalloc(size);

View File

@@ -26,6 +26,7 @@ static void
show(zone, t, v)
char * zone;
time_t t;
int v;
{
struct tm * tmp;

View File

@@ -309,6 +309,8 @@ static void
eats(name, num, rname, rnum)
char * name;
char * rname;
int num;
int rnum;
{
filename = name;
linenum = num;
@@ -319,6 +321,7 @@ char * rname;
static void
eat(name, num)
char * name;
int num;
{
eats(name, num, (char *) NULL, -1);
}
@@ -653,6 +656,7 @@ static long
gethms(string, errstring, signable)
char * string;
char * errstring;
int signable;
{
int hh, mm, ss, sign;
@@ -687,6 +691,7 @@ char * errstring;
static void
inrule(fields, nfields)
register char ** fields;
int nfields;
{
struct rule r;
@@ -713,6 +718,7 @@ register char ** fields;
static int
inzone(fields, nfields)
register char ** fields;
int nfields;
{
register int i;
char buf[132];
@@ -745,6 +751,7 @@ register char ** fields;
static int
inzcont(fields, nfields)
register char ** fields;
int nfields;
{
if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
error("wrong number of fields on Zone continuation line");
@@ -756,6 +763,8 @@ register char ** fields;
static int
inzsub(fields, nfields, iscont)
register char ** fields;
int nfields;
int iscont;
{
register char * cp;
struct zone z;
@@ -826,6 +835,7 @@ error("Zone continuation line end time is not after end time of previous line");
static void
inlink(fields, nfields)
register char ** fields;
int nfields;
{
struct link l;
@@ -1055,6 +1065,7 @@ char * name;
static void
outzone(zpfirst, zonecount)
struct zone * zpfirst;
int zonecount;
{
register struct zone * zp;
register struct rule * rp;
@@ -1200,6 +1211,7 @@ addtt(starttime, addtype(startoff, startbuf, startisdst));
static void
addtt(starttime, type)
time_t starttime;
int type;
{
if (timecnt != 0 && type == types[timecnt - 1])
return; /* easy enough! */
@@ -1216,6 +1228,7 @@ static int
addtype(gmtoff, abbr, isdst)
long gmtoff;
char * abbr;
int isdst;
{
register int i, j;
@@ -1251,6 +1264,7 @@ char * abbr;
static int
yearistype(year, type)
int year;
char * type;
{
char buf[BUFSIZ];
@@ -1276,7 +1290,7 @@ char * type;
}
static int
lowerit(a)
lowerit(int a)
{
return (isascii(a) && isupper(a)) ? tolower(a) : a;
}
@@ -1538,7 +1552,7 @@ char * name;
}
static long
eitol(i)
eitol(int i)
{
long l;

View File

@@ -112,6 +112,7 @@ void gpanel_pixel(int color, int x, int y);
void gpanel_line(int color, int x0, int y0, int x1, int y1);
void gpanel_rect(int color, int x0, int y0, int x1, int y1);
void gpanel_fill(int color, int x0, int y0, int x1, int y1);
void gpanel_fill_triangle(int color, int x0, int y0, int x1, int y1, int x2, int y2);
void gpanel_circle(int color, int x, int y, int radius);
void gpanel_image(int x, int y, int width, int height, const unsigned short *data);
void gpanel_char(const struct gpanel_font_t *font, int color, int background, int x, int y, int sym);
@@ -124,12 +125,47 @@ extern int _gpanel_fd;
/*
* Kernel driver routines.
*/
struct uio;
extern int gpanel_open(dev_t dev, int flag, int mode);
extern int gpanel_close(dev_t dev, int flag, int mode);
extern int gpanel_read(dev_t dev, struct uio *uio, int flag);
extern int gpanel_write(dev_t dev, struct uio *uio, int flag);
extern int gpanel_ioctl(dev_t dev, u_int cmd, caddr_t addr, int flag);
extern int gpanel_read_byte(void);
extern void gpanel_write_byte(int value);
extern void gpanel_cs_active(void);
extern void gpanel_cs_idle(void);
extern void gpanel_rs_command(void);
extern void gpanel_rs_data(void);
extern void gpanel_wr_strobe(void);
extern void gpanel_read_dir(void);
extern void gpanel_write_dir(void);
extern int gpanel_send_command(int value);
extern int gpanel_send_data(int value);
/*
* Descriptor for access to the hardware-level driver.
*/
struct gpanel_hw {
const char *name;
void (*resize)(struct gpanel_hw *hw, int width, int height);
void (*set_pixel)(int x, int y, int color);
void (*fill_rectangle)(int x0, int y0, int x1, int y1, int color);
void (*draw_image)(int x, int y, int width, int height,
const unsigned short *data);
void (*draw_glyph)(const struct gpanel_font_t *font,
int color, int background, int x, int y, int width,
const unsigned short *bits);
};
extern int gpanel_width;
extern int gpanel_height;
extern void st7781_init_display(struct gpanel_hw *hw);
extern void nt35702_init_display(struct gpanel_hw *hw);
extern void ili9341_init_display(struct gpanel_hw *hw);
extern void ili9481_init_display(struct gpanel_hw *hw);
extern void s6d04h0_init_display(struct gpanel_hw *hw);
#endif /* KERNEL */
#endif /* _GPANEL_H */

View File

@@ -5,7 +5,7 @@
*/
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
"elf32-littlemips")
OUTPUT_ARCH(mips)
OUTPUT_ARCH(pic32mx)
ENTRY(_reset_vector_)
MEMORY
{

View File

@@ -29,7 +29,7 @@ options "EXEC_AOUT" # Run a.out binaries
options "EXEC_ELF" # Run ELF binaries
options "EXEC_SCRIPT" # Run shell scripts
options "UCB_METER" # Collect kernel statistics
options "NPROC=10" # Number of processes, default 10
options "NPROC=10" # Number of processes, default 25
options "NBUF=10" # Number of i/o buffers, default 10
options "NFILE=24" # Number of files, default 24
options "NINODE=24" # Number of i-nodes, default 24
@@ -130,8 +130,9 @@ device picga0 at spi1 pin RA4 # chip select signal
options "PICGA_BUS=SPI1CON" # TODO: delete this option
signal "PICGA_CS" pin RA4 # TODO: delete
# ST7781 TFT display driver
device swtft
# TFT display driver with 8-bit parallel interface.
# Supported controllers: ST7781, ILI9341, NT35702
device gpanel
signal "LCD_RST" pin RB10
signal "LCD_CS" pin RB0
signal "LCD_RD" pin RB2

View File

@@ -3,7 +3,7 @@
*/
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
"elf32-littlemips")
OUTPUT_ARCH(mips)
OUTPUT_ARCH(pic32mx)
ENTRY(_reset_vector_)
MEMORY
{

View File

@@ -317,7 +317,8 @@ const struct cdevsw cdevsw[] = {
#if GPANEL_MAJOR != 16
# error Wrong GPANEL_MAJOR value!
#endif
#if defined(HXTFT_ENABLED) || defined(SWTFT_ENABLED)
#if defined(HXTFT_ENABLED) || defined(GPANEL_ENABLED) || \
defined(SGPANEL_ENABLED)
gpanel_open, gpanel_close, gpanel_read, gpanel_write,
gpanel_ioctl, nulldev, 0, seltrue,
nostrategy, 0, 0,

View File

@@ -21,7 +21,7 @@ ldscript "maximite/bootloader.ld" # Linker script
# Standard system options
options "CPU_KHZ=80000" # Oscillator frequency of CPU core
options "BUS_KHZ=40000" # Frequency of peripheral bus
options "BUS_KHZ=80000" # Frequency of peripheral bus
options "BUS_DIV=1" # Bus clock divisor 1/2/4/8
# LEDs
@@ -33,7 +33,7 @@ config unix root on sd0a
swap on sd0b
# Console options
options "CONS_MAJOR=UARTUSB_MAJOR" # UARTUSB device
options "CONS_MAJOR=UARTUSB_MAJOR" # USB device
# Virtual UART on USB
device uartusb
@@ -50,13 +50,13 @@ signal "SD0_ENA" pin RG13 # SD card enable
# General purpose I/O ports
# Flags define a mask of available pins
# The following pins excluded:
# RD1, RD2, RD3, RG12, RG13 - spi3, SD card
# RD15, RF2, RF8, RG12, RG13 - spi3, SD card
device gpio0 flags 0xc6ff # port A
device gpio1 flags 0xffff # port B
device gpio2 flags 0xf01e # port C
device gpio3 flags 0xfff1 # port D
device gpio3 flags 0x7fff # port D
device gpio4 flags 0x03ff # port E
device gpio5 flags 0x313f # port F
device gpio5 flags 0x303b # port F
device gpio6 flags 0xc3cf # port G
# ADC driver

View File

@@ -19,7 +19,7 @@ PARAM += -DUSB_NUM_STRING_DESCRIPTORS=3
PARAM += -DUSB_MAX_EP_NUMBER=3
PARAM += -DCONS_MAJOR=UARTUSB_MAJOR
PARAM += -DBUS_DIV=1
PARAM += -DBUS_KHZ=40000
PARAM += -DBUS_KHZ=80000
PARAM += -DCPU_KHZ=80000
LDSCRIPT = "maximite/bootloader.ld"
#

View File

@@ -35,7 +35,7 @@ config unix root on sd0a
options "CONS_MAJOR=UARTUSB_MAJOR" # USB device
# Virtual UART on USB
device uartusb0
device uartusb
options "USB_MAX_EP_NUMBER=3"
options "USB_NUM_STRING_DESCRIPTORS=3"
@@ -62,3 +62,20 @@ device adc
# PWM driver
device pwm
# TFT display driver with 8-bit parallel interface.
# Supported controllers: ST7781, ILI9341, NT35702
device gpanel
signal "LCD_RST" pin RB9 # arduino A4
signal "LCD_CS" pin RB7 # arduino A3
signal "LCD_RS" pin RB6 # arduino A2
signal "LCD_WR" pin RB4 # arduino A1
signal "LCD_RD" pin RB3 # arduino A0
signal "LCD_D2" pin RE2 # arduino D2
signal "LCD_D3" pin RE3 # arduino D3
signal "LCD_D4" pin RE4 # arduino D4
signal "LCD_D5" pin RE5 # arduino D5
signal "LCD_D6" pin RE6 # arduino D6
signal "LCD_D7" pin RE7 # arduino D7
signal "LCD_D0" pin RB11 # arduino D8
signal "LCD_D1" pin RB12 # arduino D9

View File

@@ -11,6 +11,20 @@ PARAM += -DGPIO5_ENABLED
PARAM += -DGPIO6_ENABLED
PARAM += -DADC_ENABLED
PARAM += -DPWM_ENABLED
PARAM += -DGPANEL_ENABLED
PARAM += -DLCD_D1_PORT=TRISB -DLCD_D1_PIN=12
PARAM += -DLCD_D0_PORT=TRISB -DLCD_D0_PIN=11
PARAM += -DLCD_D7_PORT=TRISE -DLCD_D7_PIN=7
PARAM += -DLCD_D6_PORT=TRISE -DLCD_D6_PIN=6
PARAM += -DLCD_D5_PORT=TRISE -DLCD_D5_PIN=5
PARAM += -DLCD_D4_PORT=TRISE -DLCD_D4_PIN=4
PARAM += -DLCD_D3_PORT=TRISE -DLCD_D3_PIN=3
PARAM += -DLCD_D2_PORT=TRISE -DLCD_D2_PIN=2
PARAM += -DLCD_RD_PORT=TRISB -DLCD_RD_PIN=3
PARAM += -DLCD_WR_PORT=TRISB -DLCD_WR_PIN=4
PARAM += -DLCD_RS_PORT=TRISB -DLCD_RS_PIN=6
PARAM += -DLCD_CS_PORT=TRISB -DLCD_CS_PIN=7
PARAM += -DLCD_RST_PORT=TRISB -DLCD_RST_PIN=9
PARAM += -DSD0_ENA_PORT=TRISB -DSD0_ENA_PIN=13
PARAM += -DLED_DISK_PORT=TRISB -DLED_DISK_PIN=12
PARAM += -DLED_KERNEL_PORT=TRISB -DLED_KERNEL_PIN=15
@@ -65,6 +79,7 @@ OBJS = exec_aout.o exec_conf.o exec_elf.o exec_script.o exec_subr.o \
ufs_namei.o ufs_subr.o ufs_syscalls.o ufs_syscalls2.o \
vfs_vnops.o vm_sched.o vm_swap.o vm_swp.o clock.o cons.o devsw.o \
exception.o machdep.o mem.o signal.o swap.o sysctl.o adc.o \
gpanel.o gpanel-ili9341.o gpanel-nt35702.o gpanel-st7781.o \
gpio.o pwm.o sd.o spi.o spi_bus.o usb_device.o \
usb_function_cdc.o usb_uart.o
@@ -91,7 +106,9 @@ CFILES = $S/kernel/exec_aout.c $S/kernel/exec_conf.c $S/kernel/exec_elf.c \
$S/kernel/vm_swp.c $S/pic32/clock.c $S/pic32/cons.c \
$S/pic32/devsw.c $S/pic32/exception.c $S/pic32/machdep.c \
$S/pic32/mem.c $S/pic32/signal.c $S/pic32/swap.c \
$S/pic32/sysctl.c $S/pic32/adc.c $S/pic32/gpio.c $S/pic32/pwm.c \
$S/pic32/sysctl.c $S/pic32/adc.c $S/pic32/gpanel.c \
$S/pic32/gpanel-ili9341.c $S/pic32/gpanel-nt35702.c \
$S/pic32/gpanel-st7781.c $S/pic32/gpio.c $S/pic32/pwm.c \
$S/pic32/sd.c $S/pic32/spi.c $S/pic32/spi_bus.c \
$S/pic32/usb_device.c $S/pic32/usb_function_cdc.c \
$S/pic32/usb_uart.c swapunix.c
@@ -329,6 +346,18 @@ sysctl.o: $S/pic32/sysctl.c
adc.o: $S/pic32/adc.c
${COMPILE_C}
gpanel.o: $S/pic32/gpanel.c
${COMPILE_C}
gpanel-ili9341.o: $S/pic32/gpanel-ili9341.c
${COMPILE_C}
gpanel-nt35702.o: $S/pic32/gpanel-nt35702.c
${COMPILE_C}
gpanel-st7781.o: $S/pic32/gpanel-st7781.c
${COMPILE_C}
gpio.o: $S/pic32/gpio.c
${COMPILE_C}

View File

@@ -70,6 +70,13 @@ pic32/sysctl.c standard
#
pic32/adc.c optional adc
pic32/glcd.c optional glcd
pic32/gpanel.c optional gpanel
pic32/gpanel-ili9341.c optional gpanel
pic32/gpanel-nt35702.c optional gpanel
#pic32/gpanel-s6d04h0.c optional gpanel
pic32/gpanel-st7781.c optional gpanel
pic32/gpanel-spi.c optional sgpanel
pic32/gpanel-spi-ili9341.c optional sgpanel
pic32/gpio.c optional gpio
pic32/hx8357.c optional hxtft
pic32/picga.c optional picga
@@ -81,7 +88,6 @@ pic32/sdramp.c optional dr
pic32/sdram.S optional dr
pic32/spirams.c optional sr
pic32/sramc.c optional rc
pic32/st7781.c optional swtft
pic32/skel.c optional skel
pic32/spi.c optional spi
pic32/spi_bus.c optional spi

View File

@@ -1,64 +1,8 @@
# chipKIT PIC32 compiler from UECIDE
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# PIC32 compiler from UECIDE
# Use UECIDE package from http://uecide.org/download
ifndef MIPS_GCC_PREFIX
ifdef UECIDE
MIPS_GCC_PREFIX = $(UECIDE)/compilers/pic32-tools/bin/pic32-
MIPS_GCC_FORMAT = elf32-tradlittlemips
endif
endif
# chipKIT PIC32 compiler on Linux
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Download from https://github.com/jasonkajita/chipKIT-cxx/downloads
# and unzip to /usr/local.
# Need to copy pic32-tools/pic32mx/include/stdarg.h
# to pic32-tools/lib/gcc/pic32mx/4.5.1/include.
# MPLABX C32 compiler doesn't support some functionality
# we need, so use chipKIT compiler by default.
ifndef MIPS_GCC_PREFIX
ifeq (/usr/local/pic32-tools/bin/pic32-gcc,$(wildcard /usr/local/pic32-tools/bin/pic32-gcc))
MIPS_GCC_PREFIX = /usr/local/pic32-tools/bin/pic32-
MIPS_GCC_FORMAT = elf32-tradlittlemips
endif
endif
# Generic MIPS toolchain
# ~~~~~~~~~~~~~~~~~~~~~~
# You can build it from sources, as described on page
# http://retrobsd.org/wiki/doku.php/doc/toolchain-mips
ifndef MIPS_GCC_PREFIX
ifeq (/usr/local/mips-gcc-4.8.1/bin/mips-elf-gcc,$(wildcard /usr/local/mips-gcc-4.8.1/bin/mips-elf-gcc))
MIPS_GCC_PREFIX = /usr/local/mips-gcc-4.8.1/bin/mips-elf-
endif
endif
# Mentor Sourcery CodeBench Lite toolchain
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ifndef MIPS_GCC_PREFIX
# Download a Linux binary package from
# https://sourcery.mentor.com/GNUToolchain/release2641
ifeq (/usr/local/mips-2013.11/bin/mips-sde-elf-gcc,$(wildcard /usr/local/mips-2013.11/bin/mips-sde-elf-gcc))
MIPS_GCC_PREFIX = /usr/local/mips-2013.11/bin/mips-sde-elf-
MIPS_GCC_FORMAT = elf32-tradlittlemips
endif
endif
ifndef MIPS_GCC_PREFIX
# Download a Linux binary package from
# https://sourcery.mentor.com/GNUToolchain/release2774
ifeq (/usr/local/mips-2014.05/bin/mips-sde-elf-gcc,$(wildcard /usr/local/mips-2014.05/bin/mips-sde-elf-gcc))
MIPS_GCC_PREFIX = /usr/local/mips-2014.05/bin/mips-sde-elf-
MIPS_GCC_FORMAT = elf32-tradlittlemips
endif
endif
# Imagination Codescape MIPS SDK Essentials
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Download a Linux binary package from:
# http://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/download-codescape-mips-sdk-essentials/
ifndef MIPS_GCC_ROOT
ifeq (/opt/imgtec/Toolchains/mips-mti-elf/2015.01-7,$(wildcard /opt/imgtec/Toolchains/mips-mti-elf/2015.01-7))
MIPS_GCC_ROOT = /opt/imgtec/Toolchains/mips-mti-elf/2015.01-7
ifeq ($(HOME)/.uecide/compilers/pic32-tools/bin/pic32-gcc,$(wildcard $(HOME)/.uecide/compilers/pic32-tools/bin/pic32-gcc))
MIPS_GCC_PREFIX = $(HOME)/.uecide/compilers/pic32-tools/bin/pic32-
MIPS_GCC_FORMAT = elf32-tradlittlemips
endif
endif

458
sys/pic32/gpanel-ili9341.c Normal file
View 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
View 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