Commits

Jaroslav Beran committed fb56c4c

Port to DOS and Borland Turbo C

Comments (0)

Files changed (9)

 in C programming language with place emphasis on portability and extensibility.
 
 
-2 Supported hardware
+2 Hardware supported
 --------------------
 
 2.1 Currently supported hardware
 --------------------------------
 * Linux -> /dev/parportx -> XY41xx
-This configuration is tested very well. You only need to make sure you have
+This port is tested very well. You only need to make sure you have
 rights for reading from and writing to /dev/parportx device.
 
 * FreeBSD -> /dev/ppix -> XY41xx
-This configuration is tested very well. You only need to make sure you have
+This port is tested very well. You only need to make sure you have
 rights for reading from and writing to /dev/ppix device.
 
+* FreeDOS -> LPTx -> XY41xx
+This port is tested well with Borland Turbo C 2.01 which is available for free:
+http://edn.embarcadero.com/article/20841
+
+ - use turbo c and file PLOTTER.PRJ located in src directory
+ - make sure font1.fnt is present in the same direcroty a PLOTTER.EXE
+ - this should be working in any kind of DOS OS
+
 * MS Windows -> LPTx -> XY41xx
-This configuration is not tested well. In some versions of Winows OS you need 
+This port is not tested well. In some versions of Winows OS you need 
 additional software (such as userport or porttalk22) for enabling direct access 
 to LPTx ports. See following link:
 
 
 /* Move Absolute */
 void xy_ma(PRINTER *p, int x, int y) {
-	POSITION pos = pr_get_current_position(p);
+	POSITION pos;
+	pos = pr_get_current_position(p);
 	xy_mr(p, x - pos.x, y - pos.y);
 }
 
 /* Move Relative */
 void xy_mr(PRINTER *p, int x, int y) {
+	POSITION buff;
 	xy_pen_up(p);
-	POSITION buff = pr_get_moving_buffer(p);
+	buff = pr_get_moving_buffer(p);
 	pr_set_moving_buffer(p, buff.x + x, buff.y + y);
 }
 
 /* Vector Absolute */
 void xy_va(PRINTER *p, int x, int y) {
-	//printf("xy_va X=%d, Y=%d\n", x, y);
-	POSITION pos = pr_get_current_position(p);
+	POSITION pos;
+	pos = pr_get_current_position(p);
 	xy_pen_down(p);
 	xy_move_rel(p, x - pos.x, y - pos.y);
 }
 
 /* Point Absolute */
 void xy_pa(PRINTER *p, int x, int y) {
-	POSITION pos = pr_get_current_position(p);
+	POSITION pos;
+	pos = pr_get_current_position(p);
 	xy_pen_up(p);
 	xy_move_rel(p, x - pos.x, y - pos.y);
 	xy_pen_down(p);
 
 /* Arcus */
 void xy_ar(PRINTER *p, int r, double start_arc, double end_arc) {
-	POSITION pos = pr_get_current_position(p);
+	POSITION pos;
+	int start_deg, end_deg;
+	int x, y;
+	int i;
+
+	pos = pr_get_current_position(p);
 	xy_og(p, pos.x, pos.y);
 
-	int start_deg = start_arc * 180 / M_PI;
-	int end_deg = end_arc * 180 / M_PI;
+	start_deg = start_arc * 180 / M_PI;
+	end_deg = end_arc * 180 / M_PI;
 
-	int x = (double) r * cos(start_arc);
-	int y = (double) r * sin(start_arc);
+	x = (double) r * cos(start_arc);
+	y = (double) r * sin(start_arc);
 	xy_ma(p, x, y);
 	xy_pen_down(p);
 
-	int i;
 	for (i = start_deg; i <= end_deg; i++) {
 		x = (double) r * cos((double) i / 180 * M_PI);
 		y = (double) r * sin((double) i / 180 * M_PI);
 
 /* Just Move */
 static void xy_move_rel(PRINTER *p, int x, int y) {
-	//printf("xy_move_rel X=%d, Y=%d\n", x, y);
+	double x_step, y_step;
+	int ax, ay;
+	int i;
+	int step;
 
-	double x_step = 0;
-	double y_step = 0;
-	int ax = abs(x);
-	int ay = abs(y);
+	x_step = 0;
+	y_step = 0;
+	ax = abs(x);
+	ay = abs(y);
 
 	if (ax > ay) {
 		if (y != 0) {
 		}
 	}
 
-	int i = 0;
+	i = 0;
 	while ((ax != 0) || (ay != 0)) {
 		i++;
 
 		/* move x */
-		int step = (x_step * i) - (abs(x) - ax);
+		step = (x_step * i) - (abs(x) - ax);
 		step = (ax >= step) ? step : ax;
 		pr_move(p, 1, ((x > 0) ? 1 : 0), step);
 		ax -= step;
 
 /* Draw hpgl file */
 void hpgl_draw_from_file(PRINTER *p, char *file_name) {
+	FILE *fr;
+	char c;
+	char cmd[MAX_CMD_LEN + 1];
+	int len;
 
-	FILE *fr;
 	if ((fr = fopen(file_name, "r")) == NULL) {
 		printf("Error: Cannot open file %s for reading\n", file_name);
 		return;
 	}
 
 	pr_init(p);
+	*cmd = '\0';
+	len = 0;
 
-	char c;
-	char cmd[MAX_CMD_LEN + 1];
-	*cmd = '\0';
-	int len = 0;
 	while ((c = getc(fr)) != EOF) {
 
 		if ((c == ';') || (strlen(cmd) == MAX_CMD_LEN)) {
 	}
 
 	fclose(fr);
-
 	xy_hm(p);
 }
 
 
 /* Plot Absolute */
 static void hpgl_pa(PRINTER *p, char *cmd) {
-	int x = scale * (double) getParamAsInt(cmd, 0);
-	int y = scale * (double) getParamAsInt(cmd, 1);
+	int x, y;
+
+	x = scale * (double) getParamAsInt(cmd, 0);
+	y = scale * (double) getParamAsInt(cmd, 1);
+
 	if (pen) {
 		xy_va(p, x, y);
 	} else {
 
 /* Plot Relative */
 static void hpgl_pr(PRINTER *p, char *cmd) {
-	int x = scale * (double) getParamAsInt(cmd, 0);
-	int y = scale * (double) getParamAsInt(cmd, 1);
+	int x, y;
+
+	x = scale * (double) getParamAsInt(cmd, 0);
+	y = scale * (double) getParamAsInt(cmd, 1);
+
 	if (pen) {
 		xy_vr(p, x, y);
 	} else {
 
 /* Circle */
 static void hpgl_ci(PRINTER *p, char *cmd) {
-	int r = scale * (double) getParamAsInt(cmd, 0);
+	int r;
+	r = scale * (double) getParamAsInt(cmd, 0);
 	xy_cr(p, r);
 }
 
 /* Extracts parameters from cmd */
 static int getParamAsInt(char *cmd, int which) {
-	char *p = cmd;
+	char *p;
+	int i;
+
+	p = cmd;
+
 	if (*p != '\0' && *(p + 1) != '\0') {
 		p += 2;
 	}
-	int i = 0;
+
+	i = 0;
+
 	while (*p != '\0') {
 		if (i == which) {
 			return atoi(p);
 #define DEVICE "/dev/ppi0" 
 #endif
 
-#ifdef _WIN32
+#ifdef __TURBOC__
 #define DEVICE "0x378" 
 #endif
 
 static void hpgl_demo(PRINTER *prn);
 
 
-int main(int argc, char **argv) {
-
+int main(void) {
 	PRINTER *prn;
 
 	printf("Select plotter port: (%s): ", DEVICE);
 		fprintf(stderr, "Error: Cannot access port\n");
 		return -1;
 	}
-	
+
 	while (show_menu(prn) != '0');
 
 	pr_close_printer(prn);
 }
 
 static int show_menu(PRINTER *prn) {
+	int c;
+
 	printf("---------------------------\n");
 	printf("PlotterController\n");
 	printf("Build 20140516\n");
 	printf("\n");
 	printf("Choose your option...\n");
 
-	int c = getchar();
+	c = getchar();
 	while (getchar() != '\n');
 
 	switch (c) {
 }
 
 static void test_page(PRINTER *prn) {
+	POSITION paper;
+	int x, y, r, n;
+	int i;
+	int dir;
+
 	pr_init(prn);
-	POSITION paper = pr_get_max_position(prn);
-	
+	paper = pr_get_max_position(prn);
+
 	xy_va(prn, paper.x, 0);
 	xy_va(prn, paper.x, paper.y);
 	xy_va(prn, 0, paper.y);
 	xy_write(prn, "TEST PAGE");
 
 	xy_vs(prn, 8);
-	int x = paper.x / 2;
-	int y = paper.y / 2;
-	int r = 800;
-	int n = 12;
+	x = paper.x / 2;
+	y = paper.y / 2;
+	r = 800;
+	n = 12;
 
-	int i;
-	int dir = 0;
+	dir = 0;
 	for (i = 0; i < n; i ++) {
-		int x1 = x + r * sin(M_PI / (double) n * (double) i); 
-		int y1 = y + r * cos(M_PI / (double) n * (double) i);
-		int x2 = x - r * sin(M_PI / (double) n * (double) i);
-		int y2 = y - r * cos(M_PI / (double) n * (double) i);
+		int x1, y1, x2, y2;
+		x1 = x + r * sin(M_PI / (double) n * (double) i);
+		y1 = y + r * cos(M_PI / (double) n * (double) i);
+		x2 = x - r * sin(M_PI / (double) n * (double) i);
+		y2 = y - r * cos(M_PI / (double) n * (double) i);
 		if (dir == 0) {
 			xy_ma(prn, x1, y1);
 			xy_va(prn, x2, y2);
 }
 
 static void cone_demo(PRINTER *prn) {
+	POSITION paper;
+	int rx, ry, h, n;
+	int cx1, cy1, cx2, cy2;
+	int step, dir;
+	int i;
+
 	pr_init(prn);
-	POSITION paper = pr_get_max_position(prn);
+	paper = pr_get_max_position(prn);
 
-	int rx = 200;
-	int ry = 600;
-	int h = 1500;
-	int n = 30;
+	rx = 200;
+	ry = 600;
+	h = 1500;
+	n = 30;
 
-	int cx1 = (paper.x - h) / 2;
-	int cy1 = paper.y / 2;
+	cx1 = (paper.x - h) / 2;
+	cy1 = paper.y / 2;
 
-	int cx2 = (paper.x - h) / 2 + h;
-	int cy2 = paper.y / 2;
-	int step = 360 / n;
+	cx2 = (paper.x - h) / 2 + h;
+	cy2 = paper.y / 2;
+	step = 360 / n;
 
-	int dir = 0;
-	int i;
+	dir = 0;
 	for (i = 0; i < 360; i += step) {
-		int x1 = (double) rx * sin(M_PI / 180 * i) + cx1;
-		int y1 = (double) ry * cos(M_PI / 180 * i) + cy1;
-		int x2 = (double) rx * sin(M_PI / 180 * (i + 12 * step)) + cx2;
-		int y2 = (double) ry * cos(M_PI / 180 * (i + 12 * step)) + cy2;
+		int x1, y1, x2, y2;
+		x1 = (double) rx * sin(M_PI / 180 * i) + cx1;
+		y1 = (double) ry * cos(M_PI / 180 * i) + cy1;
+		x2 = (double) rx * sin(M_PI / 180 * (i + 12 * step)) + cx2;
+		y2 = (double) ry * cos(M_PI / 180 * (i + 12 * step)) + cy2;
 		if (dir == 0) {
 			xy_ma(prn, x1, y1);
 			xy_va(prn, x2, y2);
 }
 
 static void circles_demo(PRINTER *prn) {
+	POSITION paper;
+	int r, dist;
+
 	pr_init(prn);
-	POSITION paper = pr_get_max_position(prn);
+	paper = pr_get_max_position(prn);
 
-	int r = 250;
-	int dist = 30;
+	r = 250;
+	dist = 30;
 
 	xy_ma(prn, paper.x / 2 + r * 2 + dist, paper.y / 2 + r / 2 + dist);
 	xy_cr(prn, r);
 }
 
 static void text_demo(PRINTER *prn) {
+	POSITION paper;
+	int i;
+
 	pr_init(prn);
-	POSITION paper = pr_get_max_position(prn);
+	paper = pr_get_max_position(prn);
 
 	xy_set_font_size(5);
 	xy_vs(prn, 7);
 
-	int i;
 	for (i = 0; i < 16; i++) {
 		xy_set_text_angle(M_PI * 2 / 16 * i);
 		xy_ma(prn, paper.x / 2, paper.y / 2);
 
 
 static void triangle_demo(PRINTER *prn) {
+	POSITION paper;
+	D_POSITION p;
+	double l, h, d;
+
 	pr_init(prn);
-	POSITION paper = pr_get_max_position(prn);
+	paper = pr_get_max_position(prn);
 
-	double l = 1600;
-	double h = l * cos(M_PI_2 / 3.0);
-	double d = 80;
+	l = 1600;
+	h = l * cos(M_PI_2 / 3.0);
+	d = 80;
 
-	D_POSITION p;
 	p.x = paper.x / 2 - h / 2;
 	p.y = paper.y / 2 - l / 2;
 	draw_triangle_fragment(prn, p, l, d, 0);
 }
 
 static void draw_triangle_fragment(PRINTER * prn, D_POSITION vertex, double len, double distance, double angle) {
-
-	double h = len * cos(M_PI_2 / 3.0);
-
-	D_POSITION p = _transform_position(h, len / 2, angle);
-	int x1s = vertex.x + p.x;
-	int y1s = vertex.y + p.y;
-	int x2s = vertex.x;
-	int y2s = vertex.y;
-
+	D_POSITION p;
+	double h;
+	int x1s, y1s, x2s, y2s;
 	double x1, x2, y1, y2;
 	int i;
-	int dir = 0;
+	int dir;
+
+	h = len * cos(M_PI_2 / 3.0);
+
+	p = _transform_position(h, len / 2, angle);
+	x1s = vertex.x + p.x;
+	y1s = vertex.y + p.y;
+	x2s = vertex.x;
+	y2s = vertex.y;
+
+	dir = 0;
 	for (i = 0; i < len / distance; i++) {
 		p = _transform_position(distance * cos(M_PI_2 / 3.0) * (double) i, distance * sin(M_PI_2 / 3.0) * (double) i, angle);
 		x1 = x1s - p.x;
 }
 
 static void limits_demo(PRINTER *prn) {
+	POSITION paper;
+	int i;
+
 	pr_init(prn);
-	POSITION paper = pr_get_max_position(prn);
+	paper = pr_get_max_position(prn);
 
 	xy_va(prn, paper.x, 0);
 	xy_va(prn, paper.x, paper.y);
 	xy_va(prn, 0, 0);
 
 	xy_ma(prn, paper.x / 2, paper.y / 2);
-	int i;
 	for (i = 1; i < 6; i++) {
 		xy_cr(prn, 300 * i);
 	}
 
 static void hpgl_demo(PRINTER *prn) {
 	char file_name[100];
+
 	printf("Enter HPGL file name: ");
 	scanf("%99s", file_name);
 	while (getchar() != '\n');
 
 
 /*
-*	Windows implementation
+*	DOS implementation
 *	
 */
-#ifdef _WIN32
-#include <windows.h>
-#include <conio.h>
-
-static BOOL bPrivException = FALSE;
-
-LONG WINAPI HandlerExceptionFilter ( EXCEPTION_POINTERS *pExPtrs ) {
-
-	if (pExPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION) {
-		pExPtrs->ContextRecord->Eip ++; // Skip the OUT or IN instruction that caused the exception
-		bPrivException = TRUE;
-		return EXCEPTION_CONTINUE_EXECUTION;
-	} else
-		return EXCEPTION_CONTINUE_SEARCH;
-}
+#ifdef __TURBOC__
+#include <dos.h>
 
 int open_parport(char *device) {
-
-	SetUnhandledExceptionFilter(HandlerExceptionFilter);
-	bPrivException = FALSE;
-	_inp(0x378);  // Try to access the given port address
-
-	if (bPrivException) {
-	fprintf(stderr,	"Privileged instruction exception has occured!\n\n"
-			"To use this program under Windows NT or Windows 2000\n"
-			"you need to install the driver 'UserPort.SYS' and grant\n"
-			"access to the ports used by this program.\n");
-		return 0;
-}
-	
-
-	/* To enable Bidirectional data transfer just set the "Bidirectional" bit (bit 5) in control register. */
-
+	int fd;
+	sscanf(device, "%xd", &fd);
 	/* Parallel port address */
-	return 0x378;
+	return fd;
 }
 
 int close_parport(int fd) {
 }
 
 int write_data(int fd, unsigned char data) {
-	_outp(fd, data); 
+	outport(fd, data);
 	return 0;
 }
 
-int read_data(int fd, unsigned char *data) { 
+int read_data(int fd, unsigned char *data) {
 	write_data(0x37A, 32);		/* read on */
-	usleep_win(1000);
-	*data = _inp(fd); 		/* fetch the data */
+	delay(1000);
+	*data = inport(fd); 		/* fetch the data */
 	write_data(0x37A, 0);		/* write on */
-	usleep_win(1000);
+	delay(1000);
 	return 0;
 }
 
-void usleep_win (long usec) {
-	LARGE_INTEGER lFrequency;
-	LARGE_INTEGER lEndTime;
-	LARGE_INTEGER lCurTime;
-
-	QueryPerformanceFrequency (&lFrequency);
-	if (lFrequency.QuadPart) {
-		QueryPerformanceCounter (&lEndTime);
-		lEndTime.QuadPart += (LONGLONG) usec * lFrequency.QuadPart / 1000000;
-
-		do {
-			QueryPerformanceCounter (&lCurTime);
-			Sleep(0);
-		} while (lCurTime.QuadPart < lEndTime.QuadPart);
-	}
-}
-
 #endif
 extern int read_data(int fd, unsigned char *data);
 
 /*
-*	Windows does not have usleep
+*	usleep macro
 */
-#ifdef _WIN32
-extern void usleep_win (long usec);
-#define USLEEP(t) (usleep_win(t))
+#ifdef __TURBOC__
+#include <dos.h>
+#define USLEEP(t) (delay(t))
 #else
 #include <unistd.h>
 #define USLEEP(t) (usleep(t))
-#endif /* _WIN32 */
+#endif
 
 #endif
+main.c
+graph.c
+hpgl.c
+parport.c
+printer.c
+text.c
 *	Create printer instance
 */
 PRINTER *pr_create_printer(char *device_name) {
+	PRINTER *result;
 	int fd;
 
 	if ((fd = open_parport(device_name)) == 0) {
 		return NULL;
 	}
 
-	PRINTER *result = (PRINTER *) malloc(sizeof(PRINTER));
+	result = (PRINTER *) malloc(sizeof(PRINTER));
 
 	result->parport_fd = fd;
 	result->max_position.x = MAX_X;
 	switch_direction(p, 0);
 
 	if (!is_ready(p)) {
+		int i;
 		while (!is_ready(p)) {
 			dirty_step(p);
 		}
 
 		switch_direction(p, 1);
-		int i;
 		for (i = 0; i < 50; i++) {
 			dirty_step(p);
 		}
 *	Is ready test
 */
 static int is_ready(PRINTER *p) {
+	DATA data;
+
 	set_bit(&(p->data), READY_BIT, 0);
 	write_data(p->parport_fd, p->data);
 	USLEEP(speed[p->velocity]);
 	write_data(p->parport_fd, p->data);
 	USLEEP(speed[p->velocity]);
 
-	DATA data;
 	read_data(p->parport_fd, &data);
 	return (check_bit(data, READY_BIT) == 0);
 }
 *	Do step
 */
 static void step(PRINTER *p, int repeat) {
-	int step_dir = (check_bit(p->data, DIRECTION_BIT) == 0) ? -1 : 1;
+	int step_dir;
 	int i;
+
+	step_dir = (check_bit(p->data, DIRECTION_BIT) == 0) ? -1 : 1;
 	for (i = 0; i < repeat; i++) {
 		
 		if (check_bit(p->data, XY_BIT) == 0) {
 *	Check cross limits
 */
 static int check_cross_limits(PRINTER *p) {
-	int previous = p->out_of_limits;
-	int current = (p->virtual_position.x > p->max_position.x) 
+	int previous;
+	int current;
+
+	previous = p->out_of_limits;
+	current = (p->virtual_position.x > p->max_position.x) 
 			|| (p->virtual_position.x < 0)
 			|| (p->virtual_position.y > p->max_position.y)
 			|| (p->virtual_position.y < 0);
 *	repeat		1 step = 0.1 mm
 */
 static void sync_virt_curr_position(PRINTER *p) {
-	DATA data = p->data;
+	DATA data;
 	int i;
 
+	data = p->data;
+
 	if (p->curr_position.x != p->virtual_position.x) {
 		switch_x_y(p, 1);
 		switch_direction(p, (p->curr_position.x < p->virtual_position.x));
 
 /* Write text */
 void xy_write(PRINTER *p, char *text) {
+	char *p_t;
+
 	if (load_font(FONT_DEFINITION_FILE) != 0) {
 		return;
 	}
 
-	char *p_t;
 	for (p_t = text; *p_t != '\0'; p_t++) {
 		draw_char(p, *p_t);
 	}
 
 /* draw char */
 static void draw_char(PRINTER *p, unsigned char c) {
+	char *s;
+	int cmd[FONT_CMD_SIZE];
+	D_POSITION pos;
+
 	if (c < 32) {
 		printf("char(%d)\n", c);
 		return;
 	}
 
-	char *s = font[c - 32];
-	int cmd[FONT_CMD_SIZE];
-	D_POSITION pos;
+	s = font[c - 32];
 	
 	while ((s = get_first_command(s, cmd, FONT_CMD_SIZE)) != NULL) {
 		pos = _transform_position(cmd[1] * char_size, cmd[2] * char_size, text_angle);
 
 /* Load font */
 static int load_font(char *font_definition_file) {
+	FILE *fr;
+	char line[2048];
+	int i = 0;
+
 	if (font != NULL) free_font();
 
 	if ((font = (char **) malloc(FONT_TABLE_SIZE * sizeof(char *))) == NULL) {
 		return -1;
 	}
 
-	FILE *fr;
-
 	if ((fr = fopen(font_definition_file, "r")) == NULL) {
 		printf("Error: Cannot open file %s for reading\n", font_definition_file);
 		return -1;
 	}
 
-	char line[2048];
-	int i = 0;
+	i = 0;
 	while (fgets(line, sizeof(line), fr) != NULL) {
 
 		if ((strlen(line) > 0) && strncmp(line, "#", 1) && strncmp(line, "\n", 1)) {
 
 /* Free font */
 static void free_font(void) {
+	int i;
 
 	if (font == NULL) return;
 
-	int i;
 	for (i = 0; i < FONT_TABLE_SIZE ; i++) {
 		if (font[i] != NULL) {
 			free((void *) font[i]);