changeset 1184:120561ca1209

Use HAL tables for eCos application setup
author gthomas
date Sat, 30 Aug 2003 21:30:04 +0000
parents f8c895b74b3f
children a381c8fb785d
files packages/services/gfx/mw/current/ChangeLog packages/services/gfx/mw/current/cdl/microwindows.cdl packages/services/gfx/mw/current/include/microwin/ecos_mw_app.h packages/services/gfx/mw/current/src/demos/nanox/ntetris.c packages/services/gfx/mw/current/src/demos/nanox/ntetris.h packages/services/gfx/mw/current/src/ecos/ecos_app.c packages/services/gfx/mw/current/src/ecos/nanowm_thread.c packages/services/gfx/mw/current/src/ecos/nanox_thread.c packages/services/gfx/mw/current/src/ecos/ntetris_thread.c packages/services/gfx/mw/current/src/ecos/world_thread.c
diffstat 10 files changed, 259 insertions(+), 174 deletions(-) [+]
line wrap: on
line diff
--- a/packages/services/gfx/mw/current/ChangeLog
+++ b/packages/services/gfx/mw/current/ChangeLog
@@ -1,3 +1,21 @@
+2003-08-30  Gary Thomas  <gary@mlbassoc.com>
+
+	* src/ecos/world_thread.c: 
+	* src/ecos/ntetris_thread.c: 
+	* src/ecos/nanox_thread.c: 
+	* src/ecos/nanowm_thread.c: 
+	* src/ecos/ecos_app.c: Use tables to define threads within
+	the actual application.
+
+	* src/demos/nanox/ntetris.h: 
+	* src/demos/nanox/ntetris.c: Adapt to eCos threaded environment.
+
+	* include/microwin/ecos_mw_app.h: New file - define table
+	driven API for plug-in MicroWindows applications under eCos.
+
+	* cdl/microwindows.cdl: Add support for building complete
+	application via CDL.  Also better selection of demos to run.
+
 2003-08-22  Chris Garry <cgarry@sweeneydesign.co.uk>
 
     * cdl/microwindows.cdl
--- a/packages/services/gfx/mw/current/cdl/microwindows.cdl
+++ b/packages/services/gfx/mw/current/cdl/microwindows.cdl
@@ -135,12 +135,25 @@ cdl_package CYGPKG_MICROWINDOWS {
         fonts/X6x13.c
 
     # eCos stuff
-    cdl_option CYGBLD_MICROWINDOWS_ECOS {
+    cdl_component CYGBLD_MICROWINDOWS_ECOS {
         display   "Build MicroWindows eCos support"
         default_value 0
 
         # These files are unique to eCos
-        compile ecos/ecos_init.c ecos/nanox_thread.c
+        compile ecos/ecos_init.c 
+        compile -library=libextras.a ecos/nanox_thread.c
+
+        cdl_option CYGBLD_MICROWINDOWS_ECOS_APP {
+            display  "Build complete eCos+MicroWindows application"
+            default_value 0
+            make -priority 320 {
+                <PREFIX>/bin/ecos_mw.elf : $(PREFIX)/lib/target.ld $(PREFIX)/lib/vectors.o $(PREFIX)/lib/libtarget.a $(PREFIX)/lib/libextras.a $(REPOSITORY)/$(PACKAGE)/src/ecos/ecos_app.c
+                        @sh -c "mkdir -p $(dir $@)"
+                        $(CC) -c $(INCLUDE_PATH) $(CFLAGS) -o $(PREFIX)/lib/ecos_app.o $(REPOSITORY)/$(PACKAGE)/src/ecos/ecos_app.c
+                        $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ $(PREFIX)/lib/ecos_app.o
+            }
+            
+        }
     }
 
     # eCos VNC server drivers
@@ -257,14 +270,13 @@ cdl_package CYGPKG_MICROWINDOWS {
         display   "Build MicroWindows NANOWM"
         default_value 0
 
-
         compile					\
             demos/nanowm/nanowm.c			\
             demos/nanowm/events.c			\
             demos/nanowm/wlist.c			\
             demos/nanowm/clients.c			\
-            demos/nanowm/actions.c                      \
-	    ecos/nanowm_thread.c
+            demos/nanowm/actions.c                      
+        compile -library=libextras.a ecos/nanowm_thread.c
     }
 
     # keyboard
@@ -282,13 +294,25 @@ cdl_package CYGPKG_MICROWINDOWS {
     }
 
     # keyboard
-    cdl_option CYGBLD_MICROWINDOWS_NANOX_DEMOS {
+    cdl_component CYGBLD_MICROWINDOWS_NANOX_DEMOS {
         display   "Build MicroWindows NanoX demos"
         default_value 0
 
-        compile					\
-            demos/nanox/world.c demos/nanox/ntetris.c \
-	    ecos/world_thread.c ecos/ntetris_thread.c
+        cdl_option CYGBLD_MICROWINDOWS_NANOX_DEMOS_WORLD {
+            display "Include 'world' demo"
+            default_value 0
+            no_define
+            compile demos/nanox/world.c 
+            compile -library=libextras.a ecos/world_thread.c
+        }
+
+        cdl_option CYGBLD_MICROWINDOWS_NANOX_DEMOS_NTETRIS {
+            display "Include 'nano-tetris' demo"
+            default_value 0
+            no_define
+            compile demos/nanox/ntetris.c 
+            compile -library=libextras.a ecos/ntetris_thread.c
+        }
     }
 
     cdl_component CYGPKG_MICROWINDOWS_OPTIONS {
new file mode 100644
--- /dev/null
+++ b/packages/services/gfx/mw/current/include/microwin/ecos_mw_app.h
@@ -0,0 +1,83 @@
+#ifndef CYGONCE_ECOS_MW_APP_H_
+#define CYGONCE_ECOS_MW_APP_H_
+//==========================================================================
+//
+//      ecos_mw_app.h
+//
+//      API for plug-in MicroWindows applications
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         2003-08-30
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_tables.h>
+
+#define STACKSIZE ( 65536 )
+typedef void fun(CYG_ADDRWORD);
+struct _mw_app_entry {
+    char         *name;
+    fun          *entry;
+    int          prio;
+    fun          *init;
+    cyg_handle_t t;
+    cyg_thread   t_obj;
+    char         stack[STACKSIZE];
+} CYG_HAL_TABLE_TYPE;
+
+#define _mw_app(_name_,_id_,_pri_,_init_)               \
+externC void _id_##_thread(CYG_ADDRWORD data);          \
+struct _mw_app_entry _mw_app_##_pri_##_##_id_           \
+   CYG_HAL_TABLE_QUALIFIED_ENTRY(_mw_apps,_pri_) =      \
+     { _name_, _id_##_thread, _pri_, _init_}; 
+
+#define ECOS_MW_STARTUP_PRIORITY 11
+#define ECOS_MW_NANOX_PRIORITY   (ECOS_MW_STARTUP_PRIORITY+1)
+#define ECOS_MW_KND_PRIORITY     (ECOS_MW_STARTUP_PRIORITY+2)
+#define ECOS_MW_NANOWM_PRIORITY  (ECOS_MW_STARTUP_PRIORITY+4)
+#define ECOS_MW_APP_PRIORITY     (ECOS_MW_STARTUP_PRIORITY+5)
+
+#endif  // CYGONCE_ECOS_MW_APP_H_
+// ------------------------------------------------------------------------
--- a/packages/services/gfx/mw/current/src/demos/nanox/ntetris.c
+++ b/packages/services/gfx/mw/current/src/demos/nanox/ntetris.c
@@ -91,7 +91,7 @@
 
 #include "ntetris.h"
 
-void *my_malloc(size_t size)
+static void *my_malloc(size_t size)
 {
 	void *ret;
 
@@ -104,12 +104,12 @@ void *my_malloc(size_t size)
 }
 
 #ifdef HAVE_USLEEP
-void msleep(long ms)
+static void msleep(long ms)
 {
 	usleep(ms * 1000);
 }
 #else
-void msleep(long ms)
+static void msleep(long ms)
 {
 	struct timespec req, rem;
 
@@ -130,7 +130,7 @@ void msleep(long ms)
 #endif
 
 #ifdef USE_HISCORE_FILE
-void read_hiscore(nstate *state)
+static void read_hiscore(nstate *state)
 {
 	FILE *f;
 	int i, n;
@@ -153,7 +153,7 @@ void read_hiscore(nstate *state)
 	state->hiscore = state->fhiscore = n;
 }
 
-void write_hiscore(nstate *state)
+static void write_hiscore(nstate *state)
 {
 	FILE *f;
 
@@ -172,15 +172,15 @@ void write_hiscore(nstate *state)
 	fclose(f);
 }
 #else
-void read_hiscore(nstate *state)
+static void read_hiscore(nstate *state)
 {
 	state->hiscore = 0;
 }
 
-void write_hiscore(nstate *state) {}
+static void write_hiscore(nstate *state) {}
 #endif
 
-int will_collide(nstate *state, int x, int y, int orientation)
+static int will_collide(nstate *state, int x, int y, int orientation)
 {
 	int r, c, xx, yy;
 	char ch = 0;
@@ -209,7 +209,7 @@ int will_collide(nstate *state, int x, i
 	return 0;
 }
 
-void draw_shape(nstate *state, GR_COORD x, GR_COORD y, int erase)
+static void draw_shape(nstate *state, GR_COORD x, GR_COORD y, int erase)
 {
 	int r, c, yy, xx;
 	GR_COLOR col;
@@ -232,7 +232,7 @@ void draw_shape(nstate *state, GR_COORD 
 	}
 }
 
-void draw_well(nstate *state, int forcedraw)
+static void draw_well(nstate *state, int forcedraw)
 {
 	int x, y;
 
@@ -254,7 +254,7 @@ void draw_well(nstate *state, int forced
 	GrFlush();
 }
 
-void draw_score(nstate *state)
+static void draw_score(nstate *state)
 {
 	char buf[32];
 
@@ -269,7 +269,7 @@ void draw_score(nstate *state)
 					TEXT_Y_POSITION, buf, strlen(buf), 0);
 }
 
-void draw_next_shape(nstate *state)
+static void draw_next_shape(nstate *state)
 {
 	int r, c, startx, starty, x, y;
 	char ch = 0;
@@ -302,7 +302,7 @@ void draw_next_shape(nstate *state)
 	}
 }
 
-void draw_new_game_button(nstate *state)
+static void draw_new_game_button(nstate *state)
 {
 	GrFillRect(state->new_game_button, state->buttongcb, 0, 0,
 			NEW_GAME_BUTTON_WIDTH, NEW_GAME_BUTTON_HEIGHT);
@@ -310,7 +310,7 @@ void draw_new_game_button(nstate *state)
 					TEXT_Y_POSITION, "New Game", 8, 0);
 }
 
-void draw_anticlockwise_button(nstate *state)
+static void draw_anticlockwise_button(nstate *state)
 {
 	if(!state->running_buttons_mapped) return;
 	GrFillRect(state->anticlockwise_button, state->buttongcb, 0, 0,
@@ -319,7 +319,7 @@ void draw_anticlockwise_button(nstate *s
 					TEXT_Y_POSITION, "   /", 4, 0);
 }
 
-void draw_clockwise_button(nstate *state)
+static void draw_clockwise_button(nstate *state)
 {
 	if(!state->running_buttons_mapped) return;
 	GrFillRect(state->clockwise_button, state->buttongcb, 0, 0,
@@ -328,7 +328,7 @@ void draw_clockwise_button(nstate *state
 					TEXT_Y_POSITION, "   \\", 4, 0);
 }
 
-void draw_left_button(nstate *state)
+static void draw_left_button(nstate *state)
 {
 	if(!state->running_buttons_mapped) return;
 	GrFillRect(state->left_button, state->buttongcb, 0, 0,
@@ -337,7 +337,7 @@ void draw_left_button(nstate *state)
 					TEXT_Y_POSITION, "  <", 3, 0);
 }
 
-void draw_right_button(nstate *state)
+static void draw_right_button(nstate *state)
 {
 	if(!state->running_buttons_mapped) return;
 	GrFillRect(state->right_button, state->buttongcb, 0, 0,
@@ -346,7 +346,7 @@ void draw_right_button(nstate *state)
 					TEXT_Y_POSITION, "   >", 4, 0);
 }
 
-void draw_drop_button(nstate *state)
+static void draw_drop_button(nstate *state)
 {
 	if(!state->running_buttons_mapped) return;
 	GrFillRect(state->drop_button, state->buttongcb, 0, 0,
@@ -355,7 +355,7 @@ void draw_drop_button(nstate *state)
 					TEXT_Y_POSITION, "    Drop", 8, 0);
 }
 
-void draw_pause_continue_button(nstate *state)
+static void draw_pause_continue_button(nstate *state)
 {
 	if((state->running_buttons_mapped) && (state->state == STATE_STOPPED)) {
 		GrUnmapWindow(state->pause_continue_button);
@@ -389,7 +389,7 @@ void draw_pause_continue_button(nstate *
 	}
 }
 
-int block_is_all_in_well(nstate *state)
+static int block_is_all_in_well(nstate *state)
 {
 	if(state->current_shape.y >= WELL_NOTVISIBLE)
 		return 1;
@@ -397,7 +397,7 @@ int block_is_all_in_well(nstate *state)
 	return 0;
 }
 
-void delete_line(nstate *state, int line)
+static void delete_line(nstate *state, int line)
 {
 	int x, y;
 
@@ -410,7 +410,7 @@ void delete_line(nstate *state, int line
 	draw_well(state, 0);
 }
 
-void block_reached_bottom(nstate *state)
+static void block_reached_bottom(nstate *state)
 {
 	int x, y;
 
@@ -437,7 +437,7 @@ void block_reached_bottom(nstate *state)
 	draw_next_shape(state);
 }
 
-void move_block(nstate *state, int direction)
+static void move_block(nstate *state, int direction)
 {
 	if(direction == 0) {
  		if(!state->current_shape.x) return;
@@ -467,7 +467,7 @@ void move_block(nstate *state, int direc
 	}
 }
 
-void rotate_block(nstate *state, int direction)
+static void rotate_block(nstate *state, int direction)
 {
 	int neworientation = 0;
 
@@ -491,7 +491,7 @@ void rotate_block(nstate *state, int dir
 	}
 }
 
-int drop_block_1(nstate *state)
+static int drop_block_1(nstate *state)
 {
 	if(will_collide(state, state->current_shape.x,
 				(state->current_shape.y + 1),
@@ -509,12 +509,12 @@ int drop_block_1(nstate *state)
 	return 0;
 }
 
-void drop_block(nstate *state)
+static void drop_block(nstate *state)
 {
 	while(!drop_block_1(state)) msleep(DROP_BLOCK_DELAY);
 }
 
-void handle_exposure_event(nstate *state)
+static void handle_exposure_event(nstate *state)
 {
 	GR_EVENT_EXPOSURE *event = &state->event.exposure;
 
@@ -560,7 +560,7 @@ void handle_exposure_event(nstate *state
 	}
 }
 
-void handle_mouse_event(nstate *state)
+static void handle_mouse_event(nstate *state)
 {
 	GR_EVENT_MOUSE *event = &state->event.mouse;
 
@@ -600,7 +600,7 @@ void handle_mouse_event(nstate *state)
 	}
 }
 
-void handle_keyboard_event(nstate *state)
+static void handle_keyboard_event(nstate *state)
 {
 	GR_EVENT_KEYSTROKE *event = &state->event.keystroke;
 
@@ -653,7 +653,7 @@ void handle_keyboard_event(nstate *state
 	}
 }
 
-void handle_event(nstate *state)
+static void handle_event(nstate *state)
 {
 	switch(state->event.type) {
 		case GR_EVENT_TYPE_EXPOSURE:
@@ -677,7 +677,7 @@ void handle_event(nstate *state)
 	}
 }
 
-void clear_well(nstate *state)
+static void clear_well(nstate *state)
 {
 	int x, y;
 
@@ -689,7 +689,7 @@ void clear_well(nstate *state)
 }
 
 /* Dirty hack alert- this is to avoid using any floating point math */
-int random8(int limit)
+static int random8(int limit)
 {
 	int ret;
 
@@ -698,7 +698,7 @@ int random8(int limit)
 	return ret;
 }
 
-void choose_new_shape(nstate *state)
+static void choose_new_shape(nstate *state)
 {
 	state->current_shape.type = state->next_shape.type;
 	state->current_shape.orientation = state->next_shape.orientation;
@@ -712,7 +712,7 @@ void choose_new_shape(nstate *state)
 	state->next_shape.colour = block_colours[random8(MAX_BLOCK_COLOUR)];
 }
 
-void new_game(nstate *state)
+static void new_game(nstate *state)
 {
 	clear_well(state);
 	if(state->score > state->hiscore) state->hiscore = state->score;
@@ -725,7 +725,7 @@ void new_game(nstate *state)
 	if(state->state == STATE_NEWGAME) state->state = STATE_RUNNING;
 }
 
-void init_game(nstate *state)
+static void init_game(nstate *state)
 {
 	GR_WM_PROPERTIES props;
 
@@ -875,7 +875,7 @@ void init_game(nstate *state)
 	new_game(state);
 }
 
-void calculate_timeout(nstate *state)
+static void calculate_timeout(nstate *state)
 {
 	struct timeval t;
 	long u;
@@ -886,7 +886,7 @@ void calculate_timeout(nstate *state)
 	state->timeout.tv_usec = u % 1000000;
 }
 
-unsigned long timeout_delay(nstate *state)
+static unsigned long timeout_delay(nstate *state)
 {
 	struct timeval t;
 	signed long s, m, ret;
@@ -910,7 +910,7 @@ unsigned long timeout_delay(nstate *stat
 	else return ret;
 }
 
-void do_update(nstate *state)
+static void do_update(nstate *state)
 {
 	struct timeval t;
 
@@ -924,7 +924,7 @@ void do_update(nstate *state)
 	} 
 }
 
-void do_pause(nstate *state)
+static void do_pause(nstate *state)
 {
 	draw_pause_continue_button(state);
 	while(state->state == STATE_PAUSED) {
@@ -934,7 +934,7 @@ void do_pause(nstate *state)
 	draw_pause_continue_button(state);
 }
 
-void wait_for_start(nstate *state)
+static void wait_for_start(nstate *state)
 {
 	draw_pause_continue_button(state);
 	while(state->state == STATE_STOPPED) {
@@ -946,7 +946,7 @@ void wait_for_start(nstate *state)
 	calculate_timeout(state);
 }
 
-void run_game(nstate *state)
+static void run_game(nstate *state)
 {
 	while(state->state == STATE_RUNNING) {
 		GrGetNextEventTimeout(&state->event, timeout_delay(state));
@@ -956,7 +956,7 @@ void run_game(nstate *state)
 	}
 }
 
-void main_game_loop(nstate *state)
+static void main_game_loop(nstate *state)
 {
 	wait_for_start(state);
 	while(state->state != STATE_EXIT) {
@@ -966,10 +966,15 @@ void main_game_loop(nstate *state)
 	}
 }
 
+#ifdef __ECOS
+#define main ntetris_main
+#endif
+
 int main(int argc, char *argv[])
 {
 	nstate *state = my_malloc(sizeof(nstate));
 
+        printf("state = %x\n", state);
 	init_game(state);
 	main_game_loop(state);
 
--- a/packages/services/gfx/mw/current/src/demos/nanox/ntetris.h
+++ b/packages/services/gfx/mw/current/src/demos/nanox/ntetris.h
@@ -73,7 +73,7 @@
 					(WELL_WIDTH * BLOCK_SIZE))
 #define MAIN_WINDOW_HEIGHT ((2 * BORDER_WIDTH) + \
 					(WELL_VISIBLE_HEIGHT * BLOCK_SIZE))
-#define MAIN_WINDOW_BACKGROUND_COLOUR BLUE
+#define MAIN_WINDOW_BACKGROUND_COLOUR LTBLUE
 
 #define SCORE_WINDOW_WIDTH BUTTON_WIDTH
 #define SCORE_WINDOW_HEIGHT 35
@@ -190,44 +190,44 @@ struct ntetris_state {
 };
 typedef struct ntetris_state nstate;
 
-void *my_malloc(size_t size);
-void msleep(long ms);
-void read_hiscore(nstate *state);
-void write_hiscore(nstate *state);
-int will_collide(nstate *state, int x, int y, int orientation);
-void draw_shape(nstate *state, GR_COORD x, GR_COORD y, int erase);
-void draw_well(nstate *state, int forcedraw);
-void draw_score(nstate *state);
-void draw_next_shape(nstate *state);
-void draw_new_game_button(nstate *state);
-void draw_anticlockwise_button(nstate *state);
-void draw_clockwise_button(nstate *state);
-void draw_left_button(nstate *state);
-void draw_right_button(nstate *state);
-void draw_drop_button(nstate *state);
-void draw_pause_continue_button(nstate *state);
-int block_is_all_in_well(nstate *state);
-void delete_line(nstate *state, int line);
-void block_reached_bottom(nstate *state);
-void move_block(nstate *state, int direction);
-void rotate_block(nstate *state, int direction);
-void drop_block(nstate *state);
-void handle_exposure_event(nstate *state);
-void handle_mouse_event(nstate *state);
-void handle_keyboard_event(nstate *state);
-void handle_event(nstate *state);
-void clear_well(nstate *state);
-int random8(int limit);
-void choose_new_shape(nstate *state);
-void new_game(nstate *state);
-void init_game(nstate *state);
-void calculate_timeout(nstate *state);
-unsigned long timeout_delay(nstate *state);
-void do_update(nstate *state);
-void do_pause(nstate *state);
-void wait_for_start(nstate *state);
-void run_game(nstate *state);
-void main_game_loop(nstate *state);
+static void *my_malloc(size_t size);
+static void msleep(long ms);
+static void read_hiscore(nstate *state);
+static void write_hiscore(nstate *state);
+static int will_collide(nstate *state, int x, int y, int orientation);
+static void draw_shape(nstate *state, GR_COORD x, GR_COORD y, int erase);
+static void draw_well(nstate *state, int forcedraw);
+static void draw_score(nstate *state);
+static void draw_next_shape(nstate *state);
+static void draw_new_game_button(nstate *state);
+static void draw_anticlockwise_button(nstate *state);
+static void draw_clockwise_button(nstate *state);
+static void draw_left_button(nstate *state);
+static void draw_right_button(nstate *state);
+static void draw_drop_button(nstate *state);
+static void draw_pause_continue_button(nstate *state);
+static int block_is_all_in_well(nstate *state);
+static void delete_line(nstate *state, int line);
+static void block_reached_bottom(nstate *state);
+static void move_block(nstate *state, int direction);
+static void rotate_block(nstate *state, int direction);
+static void drop_block(nstate *state);
+static void handle_exposure_event(nstate *state);
+static void handle_mouse_event(nstate *state);
+static void handle_keyboard_event(nstate *state);
+static void handle_event(nstate *state);
+static void clear_well(nstate *state);
+static int random8(int limit);
+static void choose_new_shape(nstate *state);
+static void new_game(nstate *state);
+static void init_game(nstate *state);
+static void calculate_timeout(nstate *state);
+static unsigned long timeout_delay(nstate *state);
+static void do_update(nstate *state);
+static void do_pause(nstate *state);
+static void wait_for_start(nstate *state);
+static void run_game(nstate *state);
+static void main_game_loop(nstate *state);
 
 #define LEVELS 12
 static const int delays[] = {600, 550, 500, 450, 400, 350,
--- a/packages/services/gfx/mw/current/src/ecos/ecos_app.c
+++ b/packages/services/gfx/mw/current/src/ecos/ecos_app.c
@@ -47,66 +47,17 @@
 #include <cyg/hal/hal_arch.h>           /* CYGNUM_HAL_STACK_SIZE_TYPICAL */
 #include <sys/time.h>
 #include <network.h>                    /* init_all_network_interfaces() */
-
-#define STACKSIZE ( 65536 )
-
-extern void ecos_nx_init(CYG_ADDRWORD data);
-extern void nanowm_thread(CYG_ADDRWORD data);
-extern void nanox_thread(CYG_ADDRWORD data);
-#ifdef USE_NXKBD
-extern void nxkbd_thread(CYG_ADDRWORD data);
-#endif
-#ifdef USE_NXSCRIBBLE
-extern void nxscribble_thread(CYG_ADDRWORD data);
-#endif
-#ifdef USE_LANDMINE
-extern void landmine_thread(CYG_ADDRWORD data);
-#endif
-#ifdef USE_NTETRIS
-extern void ntetris_thread(CYG_ADDRWORD data);
-#endif
-#ifdef USE_WORLD
-extern void world_thread(CYG_ADDRWORD data);
-#endif
-#ifdef USE_IMG_DEMO
-extern void img_demo_thread(CYG_ADDRWORD data);
-#endif
-static void startup_thread(CYG_ADDRWORD data);
+#include <microwin/ecos_mw_app.h>
 
-typedef void fun(CYG_ADDRWORD);
-struct nx_thread {
-    char         *name;
-    fun          *entry;
-    int          prio;
-    cyg_handle_t t;
-    cyg_thread   t_obj;
-    char         stack[STACKSIZE];
-};
+// Define table boundaries
+CYG_HAL_TABLE_BEGIN( __MW_APP_TAB__, _mw_apps );
+CYG_HAL_TABLE_END( __MW_APP_TAB_END__, _mw_apps );
+extern struct _mw_app_entry __MW_APP_TAB__[], __MW_APP_TAB_END__;
 
-struct nx_thread _threads[] = {
-    { "System startup", startup_thread,    11 },
-    { "Nano-X server",  nanox_thread,      12 },
-    { "Nano-WM",        nanowm_thread,     14 },
-#ifdef USE_NXKBD
-    { "Nano-KBD",       nxkbd_thread,      13 },
-#endif    
-#ifdef USE_IMG_DEMO
-    { "Image demo",     img_demo_thread,   20 },
-#endif
-#ifdef USE_NXSCRIBBLE
-    { "Scribble",       nxscribble_thread, 20 },
-#endif
-#ifdef USE_LANDMINE
-    { "Landmine",       landmine_thread,   19 },
-#endif
-#ifdef USE_NTETRIS
-    { "Nano-Tetris",    ntetris_thread,    18 },
-#endif
-#ifdef USE_WORLD
-    { "World Map",      world_thread,      21 },
-#endif
-};
-#define NUM(x) (sizeof(x)/sizeof(x[0]))
+static char startup_stack[STACKSIZE];
+cyg_handle_t startup_thread;
+cyg_thread   startup_thread_obj;
+
 
 // Functions not provided in eCos by standard...
 char *
@@ -137,11 +88,10 @@ strcasecmp(const char *s1, const char *s
 }
 
 static void 
-startup_thread(CYG_ADDRESS data)
+startup(CYG_ADDRESS data)
 {
     cyg_ucount32 nanox_data_index;
-    int i;
-    struct nx_thread *nx;
+    struct _mw_app_entry *nx;
 
     printf("SYSTEM INITIALIZATION in progress\n");
     printf("NETWORK:\n");
@@ -197,8 +147,8 @@ startup_thread(CYG_ADDRESS data)
     printf("data index = %d\n", nanox_data_index);
 
     printf("Creating system threads\n");
-    nx = &_threads[1];
-    for (i = 1;  i < NUM(_threads);  i++, nx++) {
+    for (nx = __MW_APP_TAB__; nx != &__MW_APP_TAB_END__;  nx++) {
+        printf("Creating %s thread\n", nx->name);
         cyg_thread_create(nx->prio,
                           nx->entry,
                           (cyg_addrword_t) nanox_data_index,
@@ -207,16 +157,12 @@ startup_thread(CYG_ADDRESS data)
                           &nx->t,
                           &nx->t_obj);
     }
-
     printf("Starting threads\n");
-    nx = &_threads[1];
-    for (i = 1;  i < NUM(_threads);  i++, nx++) {
+    for (nx = __MW_APP_TAB__; nx != &__MW_APP_TAB_END__;  nx++) {
         printf("Starting %s\n", nx->name);
         cyg_thread_resume(nx->t);
-        // Special case - run additional code, specific to this environment
-        // only after the server has had a chance to startup
-        if (i == 2) {
-            ecos_nx_init(nanox_data_index);
+        if (nx->init) {
+            (nx->init)(nanox_data_index);
         }
     }
 
@@ -225,15 +171,13 @@ startup_thread(CYG_ADDRESS data)
 
 void cyg_user_start(void)
 {
-    struct nx_thread *nx;
-
-    nx = &_threads[0];
-    cyg_thread_create(nx->prio,
-                      nx->entry,
+    // Create the initial thread and start it up
+    cyg_thread_create(ECOS_MW_STARTUP_PRIORITY,
+                      startup,
                       (cyg_addrword_t) 0,
-                      nx->name,
-                      (void *)nx->stack, STACKSIZE,
-                      &nx->t,
-                      &nx->t_obj);
-    cyg_thread_resume(nx->t);
+                      "System startup",
+                      (void *)startup_stack, STACKSIZE,
+                      &startup_thread,
+                      &startup_thread_obj);
+    cyg_thread_resume(startup_thread);
 }
--- a/packages/services/gfx/mw/current/src/ecos/nanowm_thread.c
+++ b/packages/services/gfx/mw/current/src/ecos/nanowm_thread.c
@@ -32,6 +32,10 @@
 #define MWINCLUDECOLORS
 #include "nano-X.h"
 
+#include <microwin/ecos_mw_app.h>
+
+extern void ecos_nx_init(CYG_ADDRWORD data);
+_mw_app("Nano-WM", nanowm, ECOS_MW_NANOX_PRIORITY, ecos_nx_init);
 
 //
 // Component interfaces
@@ -39,7 +43,7 @@
 
 externC int nanowm_main(int argc, char *argv[]);
 
-int 
+static void
 nanowm_thread(CYG_ADDRWORD data)
 {
     int argc = 0;
--- a/packages/services/gfx/mw/current/src/ecos/nanox_thread.c
+++ b/packages/services/gfx/mw/current/src/ecos/nanox_thread.c
@@ -32,6 +32,8 @@
 #define MWINCLUDECOLORS
 #include "nano-X.h"
 
+#include <microwin/ecos_mw_app.h>
+_mw_app("Nano-X server", nanox, ECOS_MW_NANOX_PRIORITY, 0);
 
 //
 // Component interfaces
@@ -39,11 +41,12 @@
 
 externC int nanox_main(int argc, char *argv[]);
 
-int 
+static void
 nanox_thread(CYG_ADDRWORD data)
 {
     int argc = 0;
     char **argv;
 
+        printf("%s.%d\n", __FUNCTION__, __LINE__);
     nanox_main(argc, argv);
 }
--- a/packages/services/gfx/mw/current/src/ecos/ntetris_thread.c
+++ b/packages/services/gfx/mw/current/src/ecos/ntetris_thread.c
@@ -32,6 +32,8 @@
 #define MWINCLUDECOLORS
 #include "nano-X.h"
 
+#include <microwin/ecos_mw_app.h>
+_mw_app("Nano-tetris demo", ntetris, ECOS_MW_NANOX_PRIORITY, 0);
 
 //
 // Component interfaces
@@ -39,7 +41,7 @@
 
 externC int ntetris_main(int argc, char *argv[]);
 
-int 
+static void
 ntetris_thread(CYG_ADDRWORD data)
 {
     int argc = 1;
--- a/packages/services/gfx/mw/current/src/ecos/world_thread.c
+++ b/packages/services/gfx/mw/current/src/ecos/world_thread.c
@@ -32,6 +32,8 @@
 #define MWINCLUDECOLORS
 #include "nano-X.h"
 
+#include <microwin/ecos_mw_app.h>
+_mw_app("World demo", world, ECOS_MW_APP_PRIORITY, 0);
 
 //
 // Component interfaces
@@ -39,7 +41,7 @@
 
 externC int world_main(int argc, char *argv[]);
 
-int 
+static void
 world_thread(CYG_ADDRWORD data)
 {
     int argc = 1;