diff --git a/mp2/MODULE.txt b/mp2/MODULE.txt deleted file mode 100644 index e337720..0000000 --- a/mp2/MODULE.txt +++ /dev/null @@ -1 +0,0 @@ -This directory is supposed to have a 'module' subdirectory. If it is missing, contact a TA immediately to fix it. diff --git a/mp2/Makefile b/mp2/Makefile deleted file mode 100644 index dc9e2de..0000000 --- a/mp2/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -all: mazegame tr - -HEADERS=blocks.h maze.h modex.h text.h Makefile - -CFLAGS=-g -Wall - -mazegame: mazegame.o maze.o blocks.o modex.o text.o - gcc -g -lpthread -o mazegame mazegame.o maze.o blocks.o modex.o text.o - -tr: modex.c ${HEADERS} text.o - gcc ${CFLAGS} -DTEXT_RESTORE_PROGRAM=1 -o tr modex.c text.o - -%.o: %.c ${HEADERS} - gcc ${CFLAGS} -c -o $@ $< - -%.o: %.s ${HEADERS} - gcc ${CFLAGS} -c -o $@ $< - -clean:: clear - rm -f *.o *~ a.out - -clear: - rm -f mazegame tr input - diff --git a/mp2/assert.c b/mp2/assert.c deleted file mode 100644 index 143533a..0000000 --- a/mp2/assert.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * tab:4 - * - * assert.c - support for assertions and fatal exceptions - * - * "Copyright (c) 2005-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 2 - * Creation Date: Tue Feb 1 20:26:56 2005 - * Filename: assert.c - * History: - * SL 1 Tue Feb 1 20:26:56 2005 - * First written. - * SL 2 Sun Sep 13 12:30:05 2009 - * Adapted from later MP2 versions for use with maze game. - */ - -#include -#include -#include -#include - -#include "assert.h" - -/* - * The cleanup stack is implemented as a linked list of cleanup_t structures, - * defined here. - */ -typedef struct cleanup_t { - cleanup_fn_t fn; /* the function to be called */ - void* arg; /* the argument to pass to the function */ - cleanup_t* next; /* a pointer to the next cleanup on the stack */ -} cleanup_t; - -/* Helper function prototypes; see function headers for further information. */ -static void catch_signal(int sig); -static void set_signal_behavior(int32_t num); - -/* MODULE VARIABLES */ - -/* This variable points to the top of the cleanup stack. */ -static cleanup_t* cleanup_stack = NULL; - -/* INTERFACE FUNCTIONS -- these functions serve as entry points from other modules */ - -/* - * clean_on_signals - * DESCRIPTION: Request that the stack of cleanup functions be executed - * when certain signals occur, including SIGSEGV, SIGBUS, - * SIGQUIT, and SIGINT. These signals are then allowed to - * proceed with their default behavior. In addition, - * ignores SIGTSTP. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: discards (most of) previous signal behavior specifications - * WARNING: not compatible with other redefinitions of behavior for the - * specified signals - */ -void clean_on_signals() { - struct sigaction sa; /* signal behavior definition structure */ - - /* Use helper function to set up behavior for these four signals. */ - set_signal_behavior(SIGINT); - set_signal_behavior(SIGSEGV); - set_signal_behavior(SIGBUS); - set_signal_behavior(SIGQUIT); - - /* Ignore stop requests from the keyboard (tty). */ - sa.sa_handler = SIG_IGN; - if (-1 == sigaction (SIGTSTP, &sa, NULL)) - PANIC ("writing signal action failed"); -} - -/* - * do_cleanups - * DESCRIPTION: Do all cleanups on the stack. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: executes all cleanups and frees alls structure use to - * store cleanup function information - */ -void do_cleanups() { - /* Pop until the stack is empty. */ - while (NULL != cleanup_stack) - pop_cleanup(1); -} - -/* - * pop_cleanup - * DESCRIPTION: Pop the top function from the stack of cleanup - * functions, and execute it if the argument is non-zero. - * INPUTS: execute -- popped cleanup function is executed if non-zero - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: frees the structure use to store cleanup function - * information - */ -void pop_cleanup(int execute) { - cleanup_t* c; - - /* Module interface: check for stack underflow. */ - ASSERT(NULL != cleanup_stack); - - /* Check underflow again, in case it escaped our debugging runs. */ - if (NULL != (c = cleanup_stack)) { - cleanup_stack = c->next; /* Remove top element from stack. */ - if (execute) /* Execute it if requested. */ - (*(c->fn))(c->arg); - free(c); /* And free the structure. */ - } -} - - -/* - * push_cleanup - * DESCRIPTION: Push a cleanup function on to the stack of cleanup - * functions. - * INPUTS: fn -- the cleanup function to be pushed - * arg -- the argument to the cleanup function (when called) - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: dynamically allocates a structure to store cleanup - * function information - */ -void push_cleanup(cleanup_fn_t fn, void* arg) { - cleanup_t* c; /* new cleanup stack element */ - - /* Module interface: check argument validity. */ - ASSERT(NULL != fn); - - if (NULL == (c = malloc(sizeof (*c)))) /* Create a new structure. */ - ABORT ("out of memory"); - c->fn = fn; /* Fill in the new structure. */ - c->arg = arg; - c->next = cleanup_stack; /* And push it onto the stack. */ - cleanup_stack = c; -} - -/* - * HELPER FUNCTIONS -- these functions are only called from other functions - * in this file - */ - -/* - * catch_signal - * DESCRIPTION: Signal handler used to execute cleanups before termination. - * INPUTS: sig -- signal number that invoked handler - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: executes stack of cleanup functions and regenerates - * signal to force default signal behavior - * WARNING: will loop forever if signal's default behavior is not restored - * after handler execution! - */ -static void catch_signal(int sig) { - do_cleanups(); - kill(getpid(), sig); -} - -/* - * set_signal_behavior - * DESCRIPTION: Installs a signal handler that executes the cleanup stack - * and requests that the default signal behavior be restored - * after execution of the handler. - * INPUTS: num -- signal number for which behavior should be changed - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: discards (most of) previous signal behavior specification - * WARNING: not compatible with other redefinitions of behavior for the - * specified signal - */ -static void set_signal_behavior(int32_t num) { - struct sigaction sa; /* signal behavior definition structure */ - - /* Read current signal behavior. */ - if (-1 == sigaction(num, NULL, &sa)) - PANIC("reading signal action failed"); - - /* - * Set signal handler and request restoration to default behavior of - * signal after handler executes. - */ - sa.sa_handler = catch_signal; - sa.sa_flags |= SA_ONESHOT; - - /* Install new behavior for signal. */ - if (-1 == sigaction(num, &sa, NULL)) - PANIC("writing signal action failed"); -} diff --git a/mp2/assert.h b/mp2/assert.h deleted file mode 100644 index 9909293..0000000 --- a/mp2/assert.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * tab:4 - * - * assert.h - support for assertions and fatal exceptions - * - * "Copyright (c) 2005-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 2 - * Creation Date: Tue Feb 1 20:09:44 2005 - * Filename: assert.h - * History: - * SL 1 Tue Feb 1 20:09:44 2005 - * First written. - * SL 2 Sun Sep 13 12:29:12 2009 - * Adapted from later MP2 versions for use with maze game. - */ - -#ifndef ASSERT_H -#define ASSERT_H - -#include -#include -#include -#include - -/* - * This file defines several macros to simplify management of fatal - * exceptions, including assertions (debugging tests), aborts (dump - * core), and panics. - * - * Compiling in debug mode (NDEBUG is NOT defined) produces more - * informative error messages. - * - * The macros: - * - * ASSERT(cond) -- in debug mode, tests the condition and terminates the - * program if it does not hold, printing a message with file - * and line number and dumping an image of the program to - * disk; does nothing if NDEBUG is defined - * ABORT(msg) -- prints a message, dumps an image of the program to disk, - * and terminates the program; in debug mode, the message - * also includes file and line number - * PANIC(msg) -- prints a message and terminates the program; in debug - * mode, the message also includes file and line number - * - */ -#ifndef NDEBUG -#define ABORT(msg) \ -do { \ - do_cleanups(); \ - fprintf(stderr, "ABORTED -- %s: %s:%d\n", msg, __FILE__, __LINE__); \ - abort(); \ -} while (0); -#define ASSERT(x) \ -do { \ - if (!(x)) { \ - do_cleanups(); \ - fprintf(stderr, "ASSERTION FAILED: %s:%d\n", __FILE__, __LINE__); \ - abort(); \ - } \ -} while (0); -#define PANIC(msg) \ -do { \ - do_cleanups(); \ - fprintf(stderr, "PANIC -- %s: %s:%d\n", msg, __FILE__, __LINE__); \ - exit(3); \ -} while (0); -#else /* defined(NDEBUG) */ -#define ABORT(msg) \ -do { \ - do_cleanups (); \ - abort (); \ -} while (0); -#define ASSERT(x) -#define PANIC(msg) \ -do { \ - do_cleanups(); \ - fprintf(stderr, "PANIC -- %s\n", msg); \ - exit(3); \ -} while (0); -#endif - -/* - * We maintain a stack of functions to be called when a fatal exception - * occurs. Each function takes one generic pointer argument; any - * additional arguments must be marshaled into a block and a pointer to - * the block passed to the function. - * - * Cleanups should be used in block-structured form for clarity. For - * example, - * - * push_cleanup (foo, NULL); { - * - * ... some work here (note indentation!)... - * - * } pop_cleanup (1); - * - * Any functions called inside the block that generate fatal exceptions - * then call the cleanup function (foo) before terminating the program. - */ -typedef void (*cleanup_fn_t)(void* arg); - -/* - * Request that the stack of cleanup functions be executed when certain - * signals occur, including SIGSEGV, SIGBUS, SIGQUIT, and SIGINT. These - * signals are then allowed to proceed with their default behavior. - * In addition, ignores SIGTSTP. - */ -extern void clean_on_signals(); - -/* - * Do all cleanups on the stack; this function should not normally be - * called directly; instead, use the macros above (ASSERT, ABORT, or PANIC). - */ -extern void do_cleanups(); - -/* - * Pop the top function from the stack of cleanup functions, and execute it - * if the argument is non-zero. - */ -extern void pop_cleanup(int execute); - -/* Push a cleanup function on to the stack of cleanup functions. */ -extern void push_cleanup(cleanup_fn_t fn, void* arg); - -#endif /* ASSERT_H */ diff --git a/mp2/blocks.h b/mp2/blocks.h deleted file mode 100644 index 585c579..0000000 --- a/mp2/blocks.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * tab:4 - * - * blocks.h - header file for maze block image definitions - * - * "Copyright (c) 2004-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 2 - * Creation Date: Thu Sep 9 22:15:40 2004 - * Filename: blocks.h - * History: - * SL 1 Thu Sep 9 22:15:40 2004 - * First written. - * SL 2 Sat Sep 12 12:06:20 2009 - * Integrated original release back into main code base. - */ - -#ifndef BLOCKS_H -#define BLOCKS_H - -/* - * block image dimensions in pixels; images are defined as contiguous - * sets of bytes in blocks.s - */ -#define BLOCK_X_DIM 12 -#define BLOCK_Y_DIM 12 - -/* - * CAUTION! The directions below are listed clockwise to allow the use - * of modular arithmetic for turns, e.g., turning right is +1 mod 4. The - * directions also correspond to the order of the player blocks in the - * enumeration below and in the blocks.s file. The last direction of - * motion must be used for the images--no "stopped" picture is provided. - */ -typedef enum { - DIR_UP, DIR_RIGHT, DIR_DOWN, DIR_LEFT, - NUM_DIRS, - DIR_STOP = NUM_DIRS -} dir_t; - -/* - * CAUTION! These colors are used as constants rather than symbols - * in blocks.s. - */ -#define PLAYER_CENTER_COLOR 0x20 -#define WALL_OUTLINE_COLOR 0x21 -#define WALL_FILL_COLOR 0x22 - -/* - * CAUTION! The order of blocks in this enumeration must match the - * order in blocks.s. - */ -enum { - BLOCK_, /* 16 blocks for walls with up, right, down, */ - BLOCK_U, /* and left connections to adjacent walls */ - BLOCK_R, - BLOCK_UR, - BLOCK_D, - BLOCK_UD, - BLOCK_RD, - BLOCK_URD, - BLOCK_L, - BLOCK_UL, - BLOCK_RL, - BLOCK_URL, - BLOCK_DL, - BLOCK_UDL, - BLOCK_RDL, - BLOCK_URDL, - BLOCK_EMPTY, /* empty (non-wall) maze space */ - BLOCK_SHADOW, /* obscured maze space */ - BLOCK_PLAYER_UP, /* four pictures of the player, in dir_t order */ - BLOCK_PLAYER_RIGHT, - BLOCK_PLAYER_DOWN, - BLOCK_PLAYER_LEFT, - BLOCK_PLAYER_MASK_UP, /* four masks for player images, in dir_t order */ - BLOCK_PLAYER_MASK_RIGHT, - BLOCK_PLAYER_MASK_DOWN, - BLOCK_PLAYER_MASK_LEFT, - BLOCK_FRUIT_1, /* fruit pictures */ - BLOCK_FRUIT_2, - BLOCK_FRUIT_3, - BLOCK_FRUIT_4, - BLOCK_FRUIT_5, - BLOCK_FRUIT_6, - BLOCK_FRUIT_7, LAST_FRUIT = BLOCK_FRUIT_7, - BLOCK_FRUIT_SHADOW, /* obscured fruit */ - BLOCK_EXIT, /* the exit from the maze */ - NUM_BLOCKS -}; - -/* - * CAUTION: Fruits are encoded using several bits in the maze_bit_t - * bit vector. Make sure that enough bits are used to cover the - * number of fruits defined here. - */ -#define NUM_FRUIT_TYPES (LAST_FRUIT - BLOCK_FRUIT_1 + 1) - -/* the array of block pictures defined in blocks.s */ -extern unsigned char blocks[NUM_BLOCKS][BLOCK_Y_DIM][BLOCK_X_DIM]; - -#endif /* BLOCKS_H */ diff --git a/mp2/blocks.s b/mp2/blocks.s deleted file mode 100644 index 83511fd..0000000 --- a/mp2/blocks.s +++ /dev/null @@ -1,532 +0,0 @@ -# tab:8 -# -# blocks.s -# -# "Copyright (c) 2004-2009 by Steven S. Lumetta." -# -# Permission to use, copy, modify, and distribute this software and its -# documentation for any purpose, without fee, and without written agreement is -# hereby granted, provided that the above copyright notice and the following -# two paragraphs appear in all copies of this software. -# -# IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO -# ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL -# DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -# EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED -# OF THE POSSIBILITY OF SUCH DAMAGE. -# -# THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE -# PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR -# THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, -# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." -# -# Author: Steve Lumetta -# Version: 2 -# Creation Date: Thu Sep 9 22:09:54 2004 -# Filename: blocks.s -# History: -# SL 1 Thu Sep 9 22:09:54 2004 -# First written. -# SL 2 Sat Sep 12 14:25:10 2009 -# Edited comments to avoid flaky assembler errors. -# - - -# -# see blocks.h for descriptions of blocks ; the first 16 are walls with -# possible connections to adjacent walls -# -.GLOBAL blocks - -blocks: -# 0 -- none -.BYTE 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x32, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x32, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x33, 0x32 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x33, 0x32 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x32, 0x31 -.BYTE 0x31, 0x32, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x32, 0x31 -.BYTE 0x31, 0x32, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x32, 0x31 -.BYTE 0x31, 0x32, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 - -# 1 -- up -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 - -# 02 -- right -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 - -# 3 -- up and right -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 - -# 4 -- down -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 - -# 5 -- up and down -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 - -# 6 -- right and down -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 - -# 7 -- up, right, and down -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 - -# 8 -- left -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 - -# 9 -- up and left -.BYTE 0x31, 0x34, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x34, 0x3C, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x30, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x30, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x30, 0x32 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x30, 0x32 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x30, 0x32 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x30, 0x32 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x32 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x32 -.BYTE 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 - -# 10 -- right and left -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 -.BYTE 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x30, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 - -# 11 -- up, right, and left -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 - -# 12 -- down and left -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 - -# 13 -- up, down, and left -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 - -# 14 -- right, down, and left -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 - -# 15 -- up, right, down, and left -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -.BYTE 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x31, 0x31 - -# 16 -- empty -.BYTE 0x31, 0x31, 0x31, 0x32, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x31, 0x32, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x32 -.BYTE 0x31, 0x32, 0x32, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32, 0x31, 0x31, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x33, 0x34, 0x32, 0x32, 0x31, 0x30, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x33, 0x33, 0x34, 0x32, 0x32, 0x31, 0x30, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x33, 0x33, 0x34, 0x34, 0x33, 0x32, 0x31, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x33, 0x33, 0x34, 0x34, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x31 -.BYTE 0x32, 0x32, 0x33, 0x33, 0x34, 0x33, 0x32, 0x32, 0x32, 0x32, 0x31, 0x31 -.BYTE 0x31, 0x32, 0x32, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x31, 0x31 -.BYTE 0x31, 0x31, 0x32, 0x32, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x31, 0x31 - -# 17 -- shrouded -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 - -# 18 -- player going up -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00 -.BYTE 0x00, 0x18, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x18, 0x00 -.BYTE 0x00, 0x18, 0x00, 0x07, 0x07, 0x20, 0x20, 0x07, 0x07, 0x00, 0x18, 0x00 -.BYTE 0x00, 0x19, 0x00, 0x07, 0x20, 0x20, 0x20, 0x20, 0x07, 0x00, 0x19, 0x00 -.BYTE 0x00, 0x19, 0x1A, 0x07, 0x20, 0x20, 0x20, 0x20, 0x07, 0x1A, 0x19, 0x00 -.BYTE 0x00, 0x1A, 0x1A, 0x07, 0x20, 0x20, 0x20, 0x20, 0x07, 0x1A, 0x1A, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x07, 0x07, 0x20, 0x20, 0x07, 0x07, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -# 19 -- player going right -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x1A, 0x19, 0x19, 0x18, 0x18, 0x17, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x07, 0x07, 0x20, 0x20, 0x20, 0x07, 0x07, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x07, 0x20, 0x20, 0x20, 0x20, 0x20, 0x07, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x07, 0x20, 0x20, 0x20, 0x20, 0x20, 0x07, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x07, 0x07, 0x20, 0x20, 0x20, 0x07, 0x07, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x1A, 0x19, 0x19, 0x18, 0x18, 0x17, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -# 20 -- player going down -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x07, 0x07, 0x20, 0x20, 0x07, 0x07, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x1A, 0x1A, 0x07, 0x20, 0x20, 0x20, 0x20, 0x07, 0x1A, 0x1A, 0x00 -.BYTE 0x00, 0x19, 0x1A, 0x07, 0x20, 0x20, 0x20, 0x20, 0x07, 0x1A, 0x19, 0x00 -.BYTE 0x00, 0x19, 0x00, 0x07, 0x20, 0x20, 0x20, 0x20, 0x07, 0x00, 0x19, 0x00 -.BYTE 0x00, 0x18, 0x00, 0x07, 0x07, 0x20, 0x20, 0x07, 0x07, 0x00, 0x18, 0x00 -.BYTE 0x00, 0x18, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x18, 0x00 -.BYTE 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -# 21 -- player going left -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1A, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x07, 0x07, 0x20, 0x20, 0x20, 0x07, 0x07, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x07, 0x20, 0x20, 0x20, 0x20, 0x20, 0x07, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x07, 0x20, 0x20, 0x20, 0x20, 0x20, 0x07, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x07, 0x07, 0x20, 0x20, 0x20, 0x07, 0x07, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1A, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -# 22 -- player going up mask -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -# 23 -- player going right mask -.BYTE 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 - -# 24 -- player going down mask -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01 -.BYTE 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -# 25 -- player going left mask -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 -.BYTE 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 - -# 26 -- fruit #1 -- Andrew's red apple -.BYTE 0x31, 0x02, 0x31, 0x31, 0x31, 0x31, 0x06, 0x31, 0x31, 0x31, 0x32, 0x32 -.BYTE 0x02, 0x0A, 0x0A, 0x02, 0x30, 0x06, 0x30, 0x30, 0x30, 0x31, 0x31, 0x32 -.BYTE 0x30, 0x02, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x02, 0x30, 0x30, 0x32 -.BYTE 0x30, 0x30, 0x30, 0x04, 0x0C, 0x04, 0x04, 0x02, 0x02, 0x02, 0x30, 0x30 -.BYTE 0x31, 0x30, 0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x30 -.BYTE 0x31, 0x30, 0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x30, 0x30, 0x31 -.BYTE 0x31, 0x30, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x30, 0x32, 0x32 -.BYTE 0x31, 0x30, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x30, 0x32, 0x32 -.BYTE 0x32, 0x30, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x30, 0x32, 0x32 -.BYTE 0x32, 0x30, 0x30, 0x04, 0x04, 0x04, 0x04, 0x04, 0x30, 0x30, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 - -# 27 -- fruit #2 -- grapes -.BYTE 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x31, 0x31, 0x32, 0x31, 0x0A, 0x31 -.BYTE 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x0D, 0x05, 0x00, 0x0A, 0x31, 0x32 -.BYTE 0x32, 0x32, 0x31, 0x0D, 0x05, 0x00, 0x05, 0x05, 0x05, 0x0A, 0x31, 0x32 -.BYTE 0x32, 0x32, 0x31, 0x05, 0x05, 0x05, 0x00, 0x05, 0x02, 0x31, 0x32, 0x32 -.BYTE 0x33, 0x32, 0x31, 0x00, 0x05, 0x0D, 0x00, 0x0D, 0x05, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0D, 0x05, 0x00, 0x00, 0x00, 0x05, 0x05, 0x05, 0x31, 0x32 -.BYTE 0x32, 0x31, 0x05, 0x05, 0x05, 0x0D, 0x05, 0x00, 0x05, 0x00, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x31, 0x05, 0x00, 0x05, 0x05, 0x05, 0x0D, 0x05, 0x31, 0x31 -.BYTE 0x32, 0x32, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x05, 0x05, 0x31 -.BYTE 0x32, 0x32, 0x31, 0x0D, 0x05, 0x00, 0x0D, 0x05, 0x00, 0x05, 0x31, 0x32 -.BYTE 0x32, 0x31, 0x31, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x31, 0x30, 0x31 -.BYTE 0x31, 0x31, 0x32, 0x31, 0x05, 0x31, 0x31, 0x05, 0x31, 0x32, 0x31, 0x31 - -# 28 -- fruit #3 -- Justin's white peach -.BYTE 0x31, 0x32, 0x32, 0x31, 0x06, 0x30, 0x30, 0x31, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x32, 0x32, 0x31, 0x30, 0x06, 0x30, 0x31, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x32, 0x32, 0x31, 0x30, 0x06, 0x30, 0x31, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x32, 0x31, 0x0E, 0x0C, 0x06, 0x0C, 0x0E, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x31, 0x0E, 0x0C, 0x0C, 0x0C, 0x0F, 0x0E, 0x0E, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0E, 0x0C, 0x0C, 0x0F, 0x0E, 0x0E, 0x0E, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0E, 0x0C, 0x0C, 0x0F, 0x0E, 0x0E, 0x0E, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0E, 0x0E, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0E, 0x0E, 0x31, 0x33, 0x32 -.BYTE 0x32, 0x32, 0x31, 0x0C, 0x0F, 0x0E, 0x0E, 0x0E, 0x31, 0x32, 0x33, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x31, 0x0C, 0x0E, 0x0E, 0x31, 0x32, 0x32, 0x32, 0x33 -.BYTE 0x31, 0x31, 0x32, 0x32, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x32, 0x33 - -# 29 -- fruit #4 -- strawberry -.BYTE 0x32, 0x31, 0x02, 0x0A, 0x31, 0x02, 0x31, 0x32, 0x32, 0x32, 0x31, 0x31 -.BYTE 0x32, 0x32, 0x31, 0x02, 0x02, 0x0A, 0x02, 0x31, 0x32, 0x32, 0x32, 0x31 -.BYTE 0x32, 0x31, 0x31, 0x04, 0x02, 0x04, 0x04, 0x04, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0C, 0x04, 0x04, 0x04, 0x0C, 0x04, 0x04, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x04, 0x04, 0x04, 0x0C, 0x04, 0x04, 0x04, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x04, 0x0C, 0x04, 0x04, 0x04, 0x0C, 0x04, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0C, 0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x04, 0x04, 0x04, 0x04, 0x0C, 0x04, 0x0C, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x31, 0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x31, 0x32, 0x33 -.BYTE 0x32, 0x32, 0x31, 0x0C, 0x04, 0x04, 0x0C, 0x04, 0x31, 0x31, 0x32, 0x33 -.BYTE 0x32, 0x32, 0x31, 0x04, 0x04, 0x04, 0x04, 0x04, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x32, 0x32, 0x31, 0x0C, 0x04, 0x04, 0x31, 0x32, 0x32, 0x32, 0x31 - -# 30 -- fruit #5 -- banana -.BYTE 0x31, 0x06, 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31 -.BYTE 0x31, 0x06, 0x31, 0x32, 0x32, 0x32, 0x31, 0x32, 0x32, 0x32, 0x31, 0x31 -.BYTE 0x31, 0x06, 0x0E, 0x31, 0x32, 0x32, 0x32, 0x31, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x0E, 0x0E, 0x31, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x32, 0x32 -.BYTE 0x31, 0x0E, 0x0E, 0x0E, 0x31, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x32 -.BYTE 0x32, 0x31, 0x0E, 0x0E, 0x0E, 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0E, 0x0F, 0x0E, 0x0E, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x31, 0x0E, 0x0F, 0x0E, 0x0E, 0x0E, 0x0E, 0x06, 0x31, 0x32 -.BYTE 0x39, 0x32, 0x32, 0x31, 0x0E, 0x0F, 0x0E, 0x0E, 0x0E, 0x0E, 0x06, 0x31 -.BYTE 0x32, 0x31, 0x32, 0x32, 0x31, 0x0E, 0x0E, 0x0E, 0x0E, 0x31, 0x31, 0x32 -.BYTE 0x32, 0x31, 0x31, 0x32, 0x32, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 - -# 31 -- fruit #6 -- watermelon -.BYTE 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x31, 0x31, 0x0A, 0x0A, 0x0A, 0x0A, 0x31, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x31, 0x0A, 0x0A, 0x02, 0x02, 0x0A, 0x0A, 0x0A, 0x0A, 0x31, 0x32 -.BYTE 0x31, 0x0A, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0A, 0x0A, 0x31 -.BYTE 0x02, 0x02, 0x02, 0x02, 0x0A, 0x0A, 0x0A, 0x02, 0x02, 0x02, 0x02, 0x0A -.BYTE 0x02, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x02, 0x02 -.BYTE 0x0A, 0x0A, 0x0A, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0A, 0x0A, 0x0A -.BYTE 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 -.BYTE 0x31, 0x0A, 0x0A, 0x0A, 0x02, 0x02, 0x02, 0x0A, 0x0A, 0x0A, 0x0A, 0x31 -.BYTE 0x32, 0x31, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x02, 0x02, 0x02, 0x31, 0x32 -.BYTE 0x32, 0x32, 0x31, 0x31, 0x02, 0x02, 0x02, 0x02, 0x31, 0x31, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 - -# 32 -- fruit #7 -- Dew -.BYTE 0x31, 0x31, 0x32, 0x32, 0x31, 0x02, 0x02, 0x31, 0x32, 0x32, 0x31, 0x31 -.BYTE 0x32, 0x32, 0x32, 0x31, 0x31, 0x02, 0x02, 0x31, 0x31, 0x32, 0x31, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x31, 0x02, 0x08, 0x08, 0x02, 0x31, 0x32, 0x31, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x31, 0x04, 0x02, 0x02, 0x04, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x33, 0x32, 0x31, 0x0A, 0x04, 0x04, 0x0A, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x33, 0x32, 0x31, 0x0A, 0x0F, 0x0F, 0x0A, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x33, 0x32, 0x31, 0x0A, 0x0F, 0x0A, 0x0F, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x31, 0x0A, 0x0F, 0x0A, 0x0F, 0x31, 0x32, 0x33, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x31, 0x0A, 0x0F, 0x0F, 0x0A, 0x31, 0x32, 0x33, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x31, 0x04, 0x0A, 0x0A, 0x04, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x32, 0x32, 0x31, 0x02, 0x04, 0x04, 0x02, 0x31, 0x32, 0x32, 0x32 -.BYTE 0x31, 0x32, 0x32, 0x31, 0x31, 0x02, 0x02, 0x31, 0x31, 0x32, 0x31, 0x31 - -# 33 -- hidden fruit -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x19, 0x1A, 0x1A, 0x19, 0x18, 0x17, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x19, 0x1A, 0x1A, 0x1A, 0x1A, 0x18, 0x17, 0x17, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x19, 0x1A, 0x1A, 0x1A, 0x19, 0x18, 0x17, 0x17, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x19, 0x1A, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x17, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x19, 0x1A, 0x19, 0x18, 0x18, 0x17, 0x16, 0x17, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x19, 0x19, 0x18, 0x17, 0x16, 0x17, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 -.BYTE 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 - -# 34 -- exit -.BYTE 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x0F, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F, 0x0F, 0x00 -.BYTE 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00 -.BYTE 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00 -.BYTE 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00 -.BYTE 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00 -.BYTE 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00 -.BYTE 0x0F, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00 -.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.BYTE 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 diff --git a/mp2/buglog.txt b/mp2/buglog.txt deleted file mode 100644 index e58716d..0000000 --- a/mp2/buglog.txt +++ /dev/null @@ -1,37 +0,0 @@ -MP2_BUG_LOG -author: Yuxuan Lin - -1. -DESCRIPTION: - some stupid syntax confusion between C and C++ - error: 'for' loop initial declaration used outside C99 mode -SOLUTION: - This error message indicates that in C code, I tried to declare a variable in the initialization part of the for loop - (i.e. inside the parentheses of the for loop), and this usage does not comply with the C99 standard or later. - So I declared index outside for loop. - -2. -DESCRIPTION: - status bar don't show -SOLUTION: - In modex.h, change #define IMAGE_Y_DIM from 200 to 182 inspired by version checkpoint1 gradesheet - for not showing full maze - -3. -description: when begin to move, there will be an original picture at starting point -SOLUTION: - comment out - // draw_full_block(play_x, play_y, get_player_block(last_dir)); - // show_screen(); - -4: -DESCRIPTION: - Bar did not display on screen -SOLUTION: - change - /* One display page goes at the start of video memory. */ - target_img = 0x0000; - => - target_img = 0x0600; - By changing the memory of status bar, it showed but still emulated - diff --git a/mp2/input-demo b/mp2/input-demo deleted file mode 100644 index 1365ddd..0000000 Binary files a/mp2/input-demo and /dev/null differ diff --git a/mp2/input.c b/mp2/input.c deleted file mode 100644 index 647a8ab..0000000 --- a/mp2/input.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * tab:4 - * - * input.c - source file for input control to maze game - * - * "Copyright (c) 2004-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 5 - * Creation Date: Thu Sep 9 22:25:48 2004 - * Filename: input.c - * History: - * SL 1 Thu Sep 9 22:25:48 2004 - * First written. - * SL 2 Sat Sep 12 14:34:19 2009 - * Integrated original release back into main code base. - * SL 3 Sun Sep 13 03:51:23 2009 - * Replaced parallel port with Tux controller code for demo. - * SL 4 Sun Sep 13 12:49:02 2009 - * Changed init_input order slightly to avoid leaving keyboard in odd state on failure. - * SL 5 Sun Sep 13 16:30:32 2009 - * Added a reasonably robust direct Tux control for demo mode. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "assert.h" -#include "input.h" -#include "maze.h" - -#include "tuxctl-ioctl.h" /* need to include t*/ -/* set to 1 and compile this file by itself to test functionality */ -#define TEST_INPUT_DRIVER 1 - -/* set to 1 to use tux controller; otherwise, uses keyboard input */ -#define USE_TUX_CONTROLLER 1 - -/* stores original terminal settings */ -static struct termios tio_orig; - - -int fd; -/* - * init_input - * DESCRIPTION: Initializes the input controller. As both keyboard and - * Tux controller control modes use the keyboard for the quit - * command, this function puts stdin into character mode - * rather than the usual terminal mode. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: 0 on success, -1 on failure - * SIDE EFFECTS: changes terminal settings on stdin; prints an error - * message on failure - */ -int init_input() { - struct termios tio_new; - - /* - * Set non-blocking mode so that stdin can be read without blocking - * when no new keystrokes are available. - */ - if (fcntl(fileno(stdin), F_SETFL, O_NONBLOCK) != 0) { - perror("fcntl to make stdin non-blocking"); - return -1; - } - - /* - * Save current terminal attributes for stdin. - */ - if (tcgetattr(fileno(stdin), &tio_orig) != 0) { - perror ("tcgetattr to read stdin terminal settings"); - return -1; - } - - /* - * Turn off canonical (line-buffered) mode and echoing of keystrokes - * to the monitor. Set minimal character and timing parameters so as - * to prevent delays in delivery of keystrokes to the program. - */ - tio_new = tio_orig; - tio_new.c_lflag &= ~(ICANON | ECHO); - tio_new.c_cc[VMIN] = 1; - tio_new.c_cc[VTIME] = 0; - if (tcsetattr(fileno(stdin), TCSANOW, &tio_new) != 0) { - perror("tcsetattr to set stdin terminal settings"); - return -1; - } - - /* Return success. */ - return 0; -} - -/* - * get_command - * DESCRIPTION: Reads a command from the input controller. As some - * controllers provide only absolute input (e.g., go - * right), the current direction is needed as an input - * to this routine. - * INPUTS: cur_dir -- current direction of motion - * OUTPUTS: none - * RETURN VALUE: command issued by the input controller - * SIDE EFFECTS: drains any keyboard input - */ -cmd_t get_command(dir_t cur_dir) { - static dir_t prev_cur = DIR_STOP; /* previous direction sent */ - static dir_t pushed = DIR_STOP; /* last direction pushed */ -#if (USE_TUX_CONTROLLER == 0) /* use keyboard control with arrow keys */ - static int state = 0; /* small FSM for arrow keys */ -#endif - cmd_t command; - int ch; - - /* - * If the direction of motion has changed, forget the last - * direction pushed. Otherwise, it remains active. - */ - if (prev_cur != cur_dir) { - pushed = DIR_STOP; - prev_cur = cur_dir; - } - - /* Read all characters from stdin. */ - while ((ch = getc(stdin)) != EOF) { - - /* Backquote is used to quit the game. */ - if (ch == '`') - return CMD_QUIT; - -#if (USE_TUX_CONTROLLER == 0) /* use keyboard control with arrow keys */ - /* - * Arrow keys deliver the byte sequence 27, 91, and 'A' to 'D'; - * we use a small finite state machine to identify them. - */ - if (ch == 27) - state = 1; - else if (ch == 91 && state == 1) - state = 2; - else { - if (state == 2 && ch >= 'A' && ch <= 'D') { - switch (ch) { - case 'A': pushed = DIR_UP; break; - case 'B': pushed = DIR_DOWN; break; - case 'C': pushed = DIR_RIGHT; break; - case 'D': pushed = DIR_LEFT; break; - } - } - state = 0; - } -#endif - } - - /* - * Once a direction is pushed, that command remains active - * until a turn is taken. - */ - if (pushed == DIR_STOP) - command = TURN_NONE; - else - command = (pushed - cur_dir + NUM_TURNS) % NUM_TURNS; - - return command; -} - -/* - * shutdown_input - * DESCRIPTION: Cleans up state associated with input control. Restores - * original terminal settings. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: restores original terminal settings - */ -void shutdown_input() { - (void)tcsetattr(fileno(stdin), TCSANOW, &tio_orig); -} - -/* - * display_time_on_tux - * DESCRIPTION: Show number of elapsed seconds as minutes:seconds - * on the Tux controller's 7-segment displays. - * INPUTS: num_seconds -- total seconds elapsed so far - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: changes state of controller's display - */ -void display_time_on_tux(int num_seconds) { -// #if (USE_TUX_CONTROLLER != 0) -// -// #error "Tux controller code is not operational yet." -// #endif - -} - -#if (TEST_INPUT_DRIVER == 1) -int main() { - cmd_t cmd; - dir_t dir = DIR_UP; - static const char* const cmd_name[NUM_TURNS] = { - "none", "right", "back", "left" - }; - static const char* const dir_names[4] = { - "up", "right", "down", "left" - }; - - /* Grant ourselves permission to use ports 0-1023 */ - if (ioperm(0, 1024, 1) == -1) { - perror("ioperm"); - return 3; - } - - /* provided commands to initialize file descriptor */ - fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY); - int ldisc_num = N_MOUSE; - ioctl(fd, TIOCSETD, &ldisc_num); - - unsigned long button; /* variable to test TUX_BUTTONS */ - int count=0; - printf("init!"); - ioctl(fd,TUX_INIT); /* test TUX_INIT */ - //ioctl(fd,TUX_SET_LED, 0x0d0bffff); /* test TUX_SET_LED */ - while(1){ /* test TUX_BUTTONS */ - if(count % 32 ==0){ - ioctl(fd,TUX_SET_LED, 0x0f011111); - } - ioctl(fd,TUX_BUTTONS, &button); - printf("%x", button); - printf("\n"); - count++; - } - - init_input(); - while (1) { - - printf("CURRENT DIRECTION IS %s\n", dir_names[dir]); - while ((cmd = get_command(dir)) == TURN_NONE); - if (cmd == CMD_QUIT) - break; - display_time_on_tux(83); - printf ("%s\n", cmd_name[cmd]); - dir = (dir + cmd) % 4; - } - shutdown_input(); - return 0; -} -#endif diff --git a/mp2/input.h b/mp2/input.h deleted file mode 100644 index 8832a6f..0000000 --- a/mp2/input.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * tab:4 - * - * input.h - header file for input control to maze game - * - * "Copyright (c) 2004-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 2 - * Creation Date: Thu Sep 9 22:22:00 2004 - * Filename: input.h - * History: - * SL 1 Thu Sep 9 22:22:00 2004 - * First written. - * SL 2 Sun Sep 13 04:11:44 2009 - * Changed display interface for Tux controller. - */ - -#ifndef INPUT_H -#define INPUT_H - -/* possible commands from input device, whether keyboard or game controller */ -typedef enum { - TURN_NONE, TURN_RIGHT, TURN_BACK, TURN_LEFT, - NUM_TURNS, CMD_QUIT = NUM_TURNS -} cmd_t; - -/* Initialize the input device. */ -extern int init_input(); - -/* Read a command from the input device. */ -extern cmd_t get_command(); - -/* Shut down the input device. */ -extern void shutdown_input(); - -/* - * Show the elapsed seconds on the Tux controller (no effect when - * compiled for a keyboard). - */ -extern void display_time_on_tux(int num_seconds); - -#endif /* INPUT_H */ diff --git a/mp2/maze.c b/mp2/maze.c deleted file mode 100644 index 74647d6..0000000 --- a/mp2/maze.c +++ /dev/null @@ -1,863 +0,0 @@ -/* - * tab:4 - * - * maze.c - maze generation and display functions - * - * "Copyright (c) 2004-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 3 - * Creation Date: Fri Sep 10 09:58:42 2004 - * Filename: maze.c - * History: - * SL 1 Fri Sep 10 09:58:42 2004 - * First written. - * SL 2 Sat Sep 12 14:17:45 2009 - * Integrated original release back into main code base. - * SL 3 Sat Sep 12 18:41:31 2009 - * Integrated Nate Taylor's "god mode." - */ - -#include -#include -#include -#include -#include - -#include "blocks.h" -#include "input.h" -#include "maze.h" -#include "modex.h" - -/* Set to 1 to test maze generation routines. */ -#define TEST_MAZE_GEN 0 - -/* Set to 1 to remove all walls as a debugging aid. (Nate Taylor, S07). */ -#define GOD_MODE 1 - -/* local functions--see function headers for details */ -static int mark_maze_area(int x, int y); -static void add_a_fruit_internal(); -#if (TEST_MAZE_GEN == 0) /* not used when testing maze generation */ -static unsigned char* find_block(int x, int y); -static void _add_a_fruit(int show); -#endif - -/* - * The maze array contains a one byte bit vector (maze_bit_t) for each - * location in a maze. The left and right boundaries of the maze are unified, - * i.e., column 0 also forms the right boundary via wraparound. Drawings - * for each block in the maze are chosen based on a five-point stencil - * that includes north, east, south, and west neighbor blocks. For - * simplicity, the maze array is extended with additional rows on the top - * and bottom to avoid boundary conditions. - * - * Under these assumptions, the upper left boundary of the maze is at (0,1), - * and the lower right boundary is at (2 X_DIM, 2 Y_DIM + 1). The stencil - * calculation for the lower right boundary includes the point below it, - * which is (2 X_DIM, 2 Y_DIM + 2). As the width of the maze is 2 X_DIM, - * the index of this point is 2 X_DIM + (2 Y_DIM + 2) * 2 X_DIM, or - * 2 X_DIM (2 Y_DIM + 3), and the space allocated is one larger than this - * maximum index value. - */ -static unsigned char maze[2 * MAZE_MAX_X_DIM * (2 * MAZE_MAX_Y_DIM + 3) + 1]; -static int maze_x_dim; /* horizontal dimension of maze */ -static int maze_y_dim; /* vertical dimension of maze */ -static int n_fruits; /* number of fruits in maze */ -static int exit_x, exit_y; /* lattice point of maze exit */ - -/* - * maze array index calculation macro; maze dimensions are valid only - * after a call to make_maze - */ -#define MAZE_INDEX(a,b) ((a) + ((b) + 1) * maze_x_dim * 2) - -/* - * mark_maze_area - * DESCRIPTION: Uses a breadth-first search to marks all parts of the - * maze accessible from (x,y) with the MAZE_REACH bit. - * Stops at walls and at maze locations already marked - * as reached. - * INPUTS: (x,y) -- starting coordinate within maze - * OUTPUTS: none - * RETURN VALUE: number of maze locations marked - * SIDE EFFECTS: leaves MAZE_REACH markers on marked portion of maze - */ -static int mark_maze_area(int x, int y) { - /* - * queue for breadth-first search - * - * The queue holds pointers to maze locations in memory. It is - * large enough to hold the whole maze, although it should never - * hold more than twice the minimum of rows and columns at any - * time with our maze graphs. - * - * q_start is the index of the first unexplored location in the queue - * q_end is the index just after the last unexplored location in the - * queue - * cur is the maze location being explored - */ - unsigned char* q[MAZE_MAX_X_DIM * MAZE_MAX_Y_DIM]; - int q_start, q_end; - unsigned char* cur; - - /* Mark the starting location as reached, then put it into the queue. */ - q[0] = &maze[MAZE_INDEX(x, y)]; - *(q[0]) |= MAZE_REACH; - q_start = 0; - q_end = 1; - - /* Loop until queue is empty. */ - while (q_start != q_end) { - /* Get location from front of queue. */ - cur = q[q_start++]; - - /* - * Explore four directions from current position. Maze - * construction guarantees that an adjacent open space implies - * that the subsequent space in the same direction both exists - * and is open (not a MAZE_WALL). - * - * Newly found locations are marked as reached before being - * added to the queue, which prevents the same location from - * being added when reached by multiple paths of equal length - * from the starting point. - */ - if ((cur[-2 * maze_x_dim] & MAZE_WALL) == 0 && - (cur[-4 * maze_x_dim] & MAZE_REACH) == 0) { - cur[-4 * maze_x_dim] |= MAZE_REACH; - q[q_end++] = &cur[-4 * maze_x_dim]; - } - if ((cur[1] & MAZE_WALL) == 0 && - (cur[2] & MAZE_REACH) == 0) { - cur[2] |= MAZE_REACH; - q[q_end++] = &cur[2]; - } - if ((cur[2 * maze_x_dim] & MAZE_WALL) == 0 && - (cur[4 * maze_x_dim] & MAZE_REACH) == 0) { - cur[4 * maze_x_dim] |= MAZE_REACH; - q[q_end++] = &cur[4 * maze_x_dim]; - } - if ((cur[-1] & MAZE_WALL) == 0 && - (cur[-2] & MAZE_REACH) == 0) { - cur[-2] |= MAZE_REACH; - q[q_end++] = &cur[-2]; - } - } - - /* - * The queue is empty. The number of locations marked is just q_end, - * the number that passed through the queue. - */ - return q_end; -} - -/* - * make_maze - * DESCRIPTION: Create a maze of specified dimensions. The maze is - * built as a two-dimensional lattice in which the points - * 01234 with odd indices in both dimensions are always open, - * 0 ----- those with even indices in both dimensions are always - * 1 - ? - walls, and other points are either open or walls to form - * 2 -?*?- the maze. The maze to the left is a 2x2 example. The - * 3 - ? - spaces are the four (odd,odd) lattice points. The - * 4 ----- boundary is marked with minus signs (these are always - * walls). The one (even,even) lattice point--also always - * a wall--is marked with an asterisk. Finally, the - * four question marks may or may not be walls; these - * four options are used to create different mazes. - * - * The algorithm used consists of two phases. In the first - * phase, metaphorical worms are dropped into the maze and - * allowed to wander about randomly, digging out the maze, - * until they decide to stop. More worms are added until - * all of the (odd,odd) points have been cleared. Each worm - * starts on an (odd,odd) point still marked as a wall. - * - * Once the worms have done their work, the second phase - * of the algorithm begins. This phase ensures that a path - * exists from any (odd,odd) lattice point to any other - * (odd,odd) point. First, those points connected to the - * point (1,1) are marked as reachable. Next, an unconnected - * point adjacent to a connected point is chosen at random, - * and the wall between them is removed, making another - * section of the maze reachable from (1,1). This process - * continues until most of the maze is reachable or a - * certain number of attempts have been made, at which point - * we scan the maze for such adjacent pairs (rather than - * choosing randomly) until the entire maze is reachable - * from (1,1). - * INPUTS: (x_dim,y_dim) -- size of maze - * start_fruits -- number of fruits to place in maze - * OUTPUTS: none - * RETURN VALUE: 0 on success, -1 on failure (if requested maze size - * exceeds limits set by defined values, with minimum - * (MAZE_MIN_X_DIM,MAZE_MIN_Y_DIM) and maximum - * (MAZE_MAX_X_DIM,MAZE_MAX_Y_DIM)) - * SIDE EFFECTS: leaves MAZE_REACH markers on marked portion of maze - */ -int make_maze(int x_dim, int y_dim, int start_fruits) { - /* - * worm turn weights; the first dimension is relative direction - * (number of 90-degree turns clockwise from up); the second is - * whether the resulting space is open (not a wall) or a wall. - */ - static int turn_wt[4][2] = {{1, 84}, {1, 9}, {3, 3}, {1, 9}}; - - int remaining, trials; - int x, y, wt[4], pick, dir, pref_dir, total, i; - unsigned char* cur; - - /* Check the requested size, and save in local state if it is valid. */ - if (x_dim < MAZE_MIN_X_DIM || x_dim > MAZE_MAX_X_DIM || - y_dim < MAZE_MIN_Y_DIM || y_dim > MAZE_MAX_Y_DIM) - return -1; - maze_x_dim = x_dim; - maze_y_dim = y_dim; - - /* Fill the maze with walls. */ - memset(maze, MAZE_WALL, sizeof (maze)); - - /* Seed the random number generator. */ - srandom(time (NULL)); - - /* - * 'worm' phase of maze generation - */ - - /* - * Track the number of (odd,odd) lattice points still marked - * as MAZE_WALL. - */ - remaining = maze_x_dim * maze_y_dim; - do { - /* Pick an (odd,odd) lattice point still marked as a MAZE_WALL. */ - do { - x = (random() % maze_x_dim) * 2 + 1; - y = (random() % maze_y_dim) * 2 + 1; - } while ((maze[MAZE_INDEX(x, y)] & MAZE_WALL) == 0); - - /* Empty the starting point. */ - maze[MAZE_INDEX(x, y)] = MAZE_NONE; - remaining--; - - /* The worm's initial preferred direction is random. */ - pref_dir = (random() % 4); - - /* Move around the maze until worm turns back on itself. */ - while (1) { - /* - * Choose the next direction of motion using weighted random - * selection. The directions are hardcoded. The wt array - * is the cumulative weight for each direction, and total - * holds the running total weight (==wt[3] at the end). - * A random value from 0 to total-1 is then chosen, and the - * direction picked according to the weight distribution. - * Weighting depends on direction and whether or not the - * maze location has already been visited (is not a MAZE_WALL). - * This code - */ - total = 0; - if (y > 1) - total += turn_wt[pref_dir][maze[MAZE_INDEX(x, y - 2)] == MAZE_WALL]; - wt[0] = total; - if (x < maze_x_dim * 2 - 1) - total += turn_wt[(pref_dir + 3) % 4][maze[MAZE_INDEX(x + 2, y)] == MAZE_WALL]; - wt[1] = total; - if (y < maze_y_dim * 2 - 1) - total += turn_wt[(pref_dir + 2) % 4][maze[MAZE_INDEX(x, y + 2)] == MAZE_WALL]; - wt[2] = total; - if (x > 1) - total += turn_wt[(pref_dir + 1) % 4][maze[MAZE_INDEX(x - 2, y)] == MAZE_WALL]; - wt[3] = total; - pick = (random() % total); - for (dir = 0; pick >= wt[dir]; dir++); - - /* If worm decides to turn around, it's done. */ - if (((dir - pref_dir + 4) % 4) == 2) - break; - - /* Move one space in the preferred direction. */ - pref_dir = dir; - switch (pref_dir) { - case 0: - maze[MAZE_INDEX(x, y - 1)] = MAZE_NONE; - y -=2; - break; - case 1: - maze[MAZE_INDEX(x + 1, y)] = MAZE_NONE; - x += 2; - break; - case 2: - maze[MAZE_INDEX(x, y + 1)] = MAZE_NONE; - y +=2; - break; - case 3: - maze[MAZE_INDEX(x - 1, y)] = MAZE_NONE; - x -= 2; - break; - } - - /* If necessary, the worm 'eats' the wall at the new space. */ - if (maze[MAZE_INDEX(x, y)] == MAZE_WALL) - remaining--; - maze[MAZE_INDEX(x, y)] = MAZE_NONE; - } /* loop for one worm */ - - /* - * The worm phase continues until all of the (odd,odd) lattice - * points in the maze are all empty. - */ - } while (remaining > 0); - - /* - * Begin the second phase of the algorithm, in which we guarantee - * connectivity between all (odd,odd) lattice points in the maze. - * We start by marking everything connected to (1,1). - */ - remaining = maze_x_dim * maze_y_dim - mark_maze_area (1, 1); - trials = 0; - do { - /* - * Once most of the maze is connected, or we have tried randomly - * "enough" times (arbitrarily defined as 100 times here, we scan - * the rest of the maze for opportunities for connecting new regions - * of the maze to the (1,1) lattice point. - */ - if (remaining < 20 || ++trials > 100) { - if ((x += 2) > maze_x_dim * 2) { - x -= maze_x_dim * 2; - if ((y += 2) > 2 * maze_y_dim) - y -= 2 * maze_y_dim; - } - cur = &maze[MAZE_INDEX(x, y)]; - if ((cur[0] & MAZE_REACH) != 0) - continue; - } else { - /* Pick an unconnected (odd,odd) lattice point at random. */ - do { - x = (random() % maze_x_dim) * 2 + 1; - y = (random() % maze_y_dim) * 2 + 1; - cur = &maze[MAZE_INDEX(x, y)]; - } while ((cur[0] & MAZE_REACH) != 0); - } - /* - * Try to connect the unconnected point by knocking down a wall - * in some direction. - */ - if (y > 1 && (cur[-4 * maze_x_dim] & MAZE_REACH) != 0) - cur[-2 * maze_x_dim] = MAZE_NONE; - else if (x > 1 && (cur[-2] & MAZE_REACH) != 0) - cur[-1] = MAZE_NONE; - else if (x < 2 * maze_x_dim - 1 && (cur[2] & MAZE_REACH) != 0) - cur[1] = MAZE_NONE; - else if (y < 2 * maze_y_dim - 1 && (cur[4 * maze_x_dim] & MAZE_REACH) != 0) - cur[2 * maze_x_dim] = MAZE_NONE; - else - continue; - /* - * Success! Mark the newly connected portion of the maze - * as reachable. - */ - remaining -= mark_maze_area(x, y); - } while (remaining > 0); - - /* - * Remove the MAZE_REACH markers--these are reused to mark those - * portions of the maze already seen by the player. - */ - for (x = 1; x < 2 * maze_x_dim; x += 2) - for (y = 1; y < 2 * maze_y_dim; y += 2) - maze[MAZE_INDEX(x, y)] &= ~MAZE_REACH; - -#if 0 /* Be kind and show the maze boundary at start. */ - for (x = 0; x < 2 * maze_x_dim; x++) { - maze[MAZE_INDEX(x, 0)] |= MAZE_REACH; - maze[MAZE_INDEX(x, 2 * maze_y_dim)] |= MAZE_REACH; - } - /* The value at y == 2 * maze_y_dim is the bottom of the right boundary. */ - for (y = 0; y <= 2 * maze_y_dim + 1; y++) - maze[MAZE_INDEX(0, y)] |= MAZE_REACH; -#endif - -#if GOD_MODE /* Remove all walls! */ - for (x = 1; x < 2 * maze_x_dim; x++) { - for (y = 1; y < 2 * maze_y_dim; y++) { - maze[MAZE_INDEX(x, y)] = MAZE_NONE; - } - } -#endif - - /* Put the required number of fruits in the maze. */ - n_fruits = 0; - for (i = 0; i < start_fruits; i++) - add_a_fruit_internal(); - - /* Find an unfruited maze point and put the maze exit there. */ - do { - x = (random() % maze_x_dim) * 2 + 1; - y = (random() % maze_y_dim) * 2 + 1; - } while ((maze[MAZE_INDEX(x, y)] & MAZE_FRUIT)); - maze[MAZE_INDEX(x, y)] |= MAZE_EXIT; - exit_x = x; - exit_y = y; - - return 0; -} - -/* - * The functions inside the preprocessor block below rely on block image - * data in blocks.s. These external data are neither available nor - * necessary for testing maze generation, and are omitted to simplify - * linking the test program (i.e., when TEST_MAZE_GEN is 1). - */ -#if (TEST_MAZE_GEN == 0) - -/* - * find_block - * DESCRIPTION: Find the appropriate image to be used for a given maze - * lattice point. - * INPUTS: (x,y) -- the maze lattice point - * OUTPUTS: none - * RETURN VALUE: a pointer to an image of a BLOCK_X_DIM x BLOCK_Y_DIM - * block of data with one byte per pixel laid out as a - * C array of dimension [BLOCK_Y_DIM][BLOCK_X_DIM] - * SIDE EFFECTS: none - */ -static unsigned char* find_block(int x, int y) { - int fnum; /* fruit found */ - int pattern; /* stencil pattern for surrounding walls */ - - /* Record whether fruit is present. */ - fnum = (maze[MAZE_INDEX(x, y)] & MAZE_FRUIT) / MAZE_FRUIT_1; - - /* The exit is always visible once the last fruit is collected. */ - if (n_fruits == 0 && (maze[MAZE_INDEX(x, y)] & MAZE_EXIT) != 0) - return (unsigned char*)blocks[BLOCK_EXIT]; - - /* - * Everything else not reached is shrouded in mist, although fruits - * show up as bumps. - */ - if ((maze[MAZE_INDEX(x, y)] & MAZE_REACH) == 0) { - if (fnum != 0) - return (unsigned char*)blocks[BLOCK_FRUIT_SHADOW]; - return (unsigned char*)blocks[BLOCK_SHADOW]; - } - - /* Show fruit. */ - if (fnum != 0) - return (unsigned char*)blocks[BLOCK_FRUIT_1 + fnum - 1]; - - /* Show empty space. */ - if ((maze[MAZE_INDEX(x, y)] & MAZE_WALL) == 0) - return (unsigned char*)blocks[BLOCK_EMPTY]; - - /* Show different types of walls. */ - pattern = (((maze[MAZE_INDEX(x, y - 1)] & MAZE_WALL) != 0) << 0) | - (((maze[MAZE_INDEX(x + 1, y)] & MAZE_WALL) != 0) << 1) | - (((maze[MAZE_INDEX(x, y + 1)] & MAZE_WALL) != 0) << 2) | - (((maze[MAZE_INDEX(x - 1, y)] & MAZE_WALL) != 0) << 3); - return (unsigned char*)blocks[pattern]; -} - -/* - * fill_horiz_buffer - * DESCRIPTION: Given the (x,y) map pixel coordinate of the leftmost - * pixel of a line to be drawn on the screen, this routine - * produces an image of the line. Each pixel on the line - * is represented as a single byte in the image. - * INPUTS: (x,y) -- leftmost pixel of line to be drawn - * OUTPUTS: buf -- buffer holding image data for the line - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -void fill_horiz_buffer(int x, int y, unsigned char buf[SCROLL_X_DIM]) { - int map_x, map_y; /* maze lattice point of the first block on line */ - int sub_x, sub_y; /* sub-block address */ - int idx; /* loop index over pixels in the line */ - unsigned char* block; /* pointer to current maze block image */ - - /* Find the maze lattice point and the pixel address within that block. */ - map_x = x / BLOCK_X_DIM; - map_y = y / BLOCK_Y_DIM; - sub_x = x - map_x * BLOCK_X_DIM; - sub_y = y - map_y * BLOCK_Y_DIM; - - /* Loop over pixels in line. */ - for (idx = 0; idx < SCROLL_X_DIM; ) { - - /* Find address of block to be drawn. */ - block = find_block(map_x++, map_y) + sub_y * BLOCK_X_DIM + sub_x; - - /* Write block colors from one line into buffer. */ - for (; idx < SCROLL_X_DIM && sub_x < BLOCK_X_DIM; idx++, sub_x++) - buf[idx] = *block++; - - /* - * All subsequent blocks are copied starting from the left side - * of the block. - */ - sub_x = 0; - } -} - -/* - * fill_vert_buffer - * DESCRIPTION: Given the (x,y) map pixel coordinate of the top pixel of - * a vertical line to be drawn on the screen, this routine - * produces an image of the line. Each pixel on the line - * is represented as a single byte in the image. - * INPUTS: (x,y) -- top pixel of line to be drawn - * OUTPUTS: buf -- buffer holding image data for the line - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -void fill_vert_buffer(int x, int y, unsigned char buf[SCROLL_Y_DIM]) { - int map_x, map_y; /* maze lattice point of the first block on line */ - int sub_x, sub_y; /* sub-block address */ - int idx; /* loop index over pixels in the line */ - unsigned char* block; /* pointer to current maze block image */ - - /* Find the maze lattice point and the pixel address within that block. */ - map_x = x / BLOCK_X_DIM; - map_y = y / BLOCK_Y_DIM; - sub_x = x - map_x * BLOCK_X_DIM; - sub_y = y - map_y * BLOCK_Y_DIM; - - /* Loop over pixels in line. */ - for (idx = 0; idx < SCROLL_Y_DIM; ) { - - /* Find address of block to be drawn. */ - block = find_block(map_x, map_y++) + sub_y * BLOCK_X_DIM + sub_x; - - /* Write block colors from one line into buffer. */ - for (; idx < SCROLL_Y_DIM && sub_y < BLOCK_Y_DIM; - idx++, sub_y++, block += BLOCK_X_DIM) - buf[idx] = *block; - - /* - * All subsequent blocks are copied starting from the top - * of the block. - */ - sub_y = 0; - } - - return; -} - -/* - * unveil_space - * DESCRIPTION: Unveils a maze lattice point (marks as MAZE_REACH, which - * means that it is drawn normally rather than as under mist), - * redrawing it if necessary. - * INPUTS: (x,y) -- the lattice point to be unveiled - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: may draw to the screen - */ -void unveil_space(int x, int y) { - unsigned char* cur; /* pointer to the maze lattice point */ - - /* - * There's a wee bitty little bug in this function in the sense - * that, if the left boundary is exposed, and the player reaches - * the right boundary without scrolling the screen, the right - * boundary will not be redrawn, and will appear to remain obscured. - * One fix is to draw both left and right boundaries when unveiling - * a left/right boundary block. But it doesn't matter much, since - * left and right boundaries aren't on the screen at the same time - * anyway for our mazes. - */ - - /* - * Allow exposure of bottom and right boundaries (left and right - * boundaries are the same lattice point in the maze). - */ - if (x < 0 || x > 2 * maze_x_dim || y < 0 || y > 2 * maze_y_dim) - return; - - /* Has the location already been seen? If so, do nothing. */ - cur = &maze[MAZE_INDEX(x, y)]; - if (*cur & MAZE_REACH) - return; - - /* Unveil the location and redraw it. */ - *cur |= MAZE_REACH; - draw_full_block (x * BLOCK_X_DIM, y * BLOCK_Y_DIM, find_block(x, y)); -} - -/* - * check_for_fruit - * DESCRIPTION: Checks a maze lattice point for fruit, eats the fruit if - * one is present (i.e., removes it from the maze), and updates - * the number of fruits (including displayed number). - * INPUTS: (x,y) -- the lattice point to be checked for fruit - * OUTPUTS: none - * RETURN VALUE: fruit number found (1 to NUM_FRUITS), or 0 for no fruit - * SIDE EFFECTS: may draw to the screen (empty fruit and, once last fruit - * is eaten, the maze exit) - */ -int check_for_fruit(int x, int y) { - int fnum; /* fruit number found */ - - /* If outside the feasible fruit range, return no fruit. */ - if (x < 0 || x >= 2 * maze_x_dim || y < 0 || y >= 2 * maze_y_dim) - return 0; - - /* Calculate the fruit number. */ - fnum = (maze[MAZE_INDEX(x, y)] & MAZE_FRUIT) / MAZE_FRUIT_1; - - /* If fruit was present... */ - if (fnum != 0) { - /* ...remove it. */ - maze[MAZE_INDEX(x, y)] &= ~MAZE_FRUIT; - - /* Update the count of fruits. */ - --n_fruits; - - /* The exit may appear. */ - if (n_fruits == 0) - draw_full_block (exit_x * BLOCK_X_DIM, exit_y * BLOCK_Y_DIM, find_block(exit_x, exit_y)); - - /* Redraw the space with no fruit. */ - draw_full_block (x * BLOCK_X_DIM, y * BLOCK_Y_DIM, find_block(x, y)); - } - - /* Return the fruit number found. */ - return fnum; -} - -/* - * check_for_win - * DESCRIPTION: Checks whether the play has won the maze by reaching a - * given maze lattice point. Winning occurs when no fruits - * remain in the maze, and the player reaches the maze exit. - * INPUTS: (x,y) -- the lattice point at which the player has arrived - * OUTPUTS: none - * RETURN VALUE: 1 if player has won, 0 if not - * SIDE EFFECTS: none - */ -int check_for_win(int x, int y) { - /* Check that position falls within valid boundaries for exit. */ - if (x < 0 || x >= 2 * maze_x_dim || y < 0 || y >= 2 * maze_y_dim) - return 0; - - /* Return win condition. */ - return (n_fruits == 0 && (maze[MAZE_INDEX(x, y)] & MAZE_EXIT) != 0); -} - -/* - * _add_a_fruit - * DESCRIPTION: Add a fruit to a random (odd,odd) lattice point in the - * maze. Update the number of fruits, including the displayed - * value. If requested, draw the new fruit on the screen. - * INPUTS: show -- 1 if new fruit should be drawn, 0 if not - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: changes displayed fruit value, may draw to screen - */ -static void _add_a_fruit(int show) { - int x, y; /* lattice point for new fruit */ - - /* - * Pick an unfruited lattice point at random. Could fall on the - * maze exit, if that is already defined. - */ - do { - x = (random() % maze_x_dim) * 2 + 1; - y = (random() % maze_y_dim) * 2 + 1; - } while ((maze[MAZE_INDEX(x, y)] & MAZE_FRUIT)); - - /* Add a random fruit to that location. */ - maze[MAZE_INDEX(x, y)] |= ((random() % NUM_FRUIT_TYPES) + 1) * MAZE_FRUIT_1; - - /* Update the number of fruits. */ - ++n_fruits; - - /* If necessary, draw the fruit on the screen. */ - if (show) - draw_full_block (x * BLOCK_X_DIM, y * BLOCK_Y_DIM, find_block(x, y)); -} - -/* - * add_a_fruit - * DESCRIPTION: Add a fruit to a random (odd, odd) lattice point in the - * maze. Update the number of fruits, including the displayed - * value. Draw the new fruit on the screen. If the new fruit - * is the only one in the maze, erase the maze exit. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: the number of fruits in the maze (after addition) - * SIDE EFFECTS: changes displayed fruit value, may draw to screen - */ -int add_a_fruit() { - /* Most of the work is done by a helper function. */ - _add_a_fruit(1); - - /* The exit may disappear. */ - if (n_fruits == 1) - draw_full_block (exit_x * BLOCK_X_DIM, exit_y * BLOCK_Y_DIM, - find_block(exit_x, exit_y)); - - /* Return the current number of fruits in the maze. */ - return n_fruits; -} - -/* - * add_a_fruit_internal - * DESCRIPTION: Add a fruit to a random (odd,odd) lattice point in the - * maze. Update the number of fruits, including the displayed - * value. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: changes displayed fruit value - */ -static void add_a_fruit_internal() { - /* - * Call a helper function, indicating that fruit should not be drawn - * on the screen at this point. - */ - _add_a_fruit(0); -} - -/* - * get_player_block - * DESCRIPTION: Get a graphical image for the player. - * INPUTS: cur_dir -- current direction of motion for the player - * OUTPUTS: none - * RETURN VALUE: a pointer to an image of a BLOCK_X_DIM x BLOCK_Y_DIM - * block of data with one byte per pixel laid out as a - * C array of dimension [BLOCK_Y_DIM][BLOCK_X_DIM] - * SIDE EFFECTS: none - */ -unsigned char* get_player_block(dir_t cur_dir) { - return (unsigned char*)blocks[BLOCK_PLAYER_UP + cur_dir]; -} - -/* - * get_player_mask - * DESCRIPTION: Get a graphical mask for the player. - * INPUTS: cur_dir -- current direction of motion for the player - * OUTPUTS: none - * RETURN VALUE: a pointer to an image of a BLOCK_X_DIM x BLOCK_Y_DIM - * block of data with one byte per pixel laid out as a - * C array of dimension [BLOCK_Y_DIM][BLOCK_X_DIM]; - * the bytes in this block indicate whether or not the - * corresponding byte in the player image should be - * drawn (1 is drawn/opaque, 0 is not drawn/fully - * transparent) - * SIDE EFFECTS: none - */ -unsigned char* get_player_mask(dir_t cur_dir) { - return (unsigned char*)blocks[BLOCK_PLAYER_MASK_UP + cur_dir]; -} - -/* - * find_open_directions - * DESCRIPTION: Determine which directions are open to movement from a - * given maze point. - * INPUTS: (x,y) -- lattice point of interest in maze - * OUTPUTS: open[] -- array of boolean values indicating that a direction - * is open; indexed by DIR_* enumeration values - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -void find_open_directions(int x, int y, int op[NUM_DIRS]) { - op[DIR_UP] = (0 == (maze[MAZE_INDEX(x, y - 1)] & MAZE_WALL)); - op[DIR_RIGHT] = (0 == (maze[MAZE_INDEX(x + 1, y)] & MAZE_WALL)); - op[DIR_DOWN] = (0 == (maze[MAZE_INDEX(x, y + 1)] & MAZE_WALL)); - op[DIR_LEFT] = (0 == (maze[MAZE_INDEX(x - 1, y)] & MAZE_WALL)); -} - -/* - * get_fruit_num - * DESCRIPTION: get number of fruit in maze. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: n_fruits - * SIDE EFFECTS: none - */ -int get_fruit_num(){ - return n_fruits; -} - -#else /* TEST_MAZE_GEN == 1 */ -/* - * The code here allows you to test the maze generation routines visually - * by creating a maze and printing it to the screen. - */ - -/* - * print_maze - * DESCRIPTION: Print a maze as ASCII text. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: prints to stdout - */ -void print_maze() { - int i; /* vertical loop index */ - int j; /* horizontal loop index */ - - /* Loop over maze rows. */ - for (i = 0; i <= 2 * maze_y_dim; i++) { - - /* Loop over maze columns. */ - for (j = 0; j <= 2 * maze_x_dim; j++) { - - /* - * Print open spaces and walls, reached and unreached, as - * distinct characters. - */ - printf("%c", - ((maze[MAZE_INDEX(j, i)] & MAZE_WALL) ? - ((maze[MAZE_INDEX(j, i)] & MAZE_REACH) ? '*' : '%') : - ((maze[MAZE_INDEX(j, i)] & MAZE_REACH) ? '.' : ' '))); - } - - /* End the printed line. */ - puts(""); - } -} - -/* - * This function is called in maze generation. We define a stub to keep - * the linker happy. - */ -static void add_a_fruit_internal() {} - -/* - * main - * DESCRIPTION: main program for testing maze generation; hardwired to - * build and print a maze of a certain size - * INPUTS: none (command line arguments are ignored) - * OUTPUTS: none - * RETURN VALUE: 0 on success (always!) - */ -int main() { - make_maze(20, 20, 0); - print_maze(); - return 0; -} - -#endif /* TEST_MAZE_GEN */ diff --git a/mp2/maze.h b/mp2/maze.h deleted file mode 100644 index bccd122..0000000 --- a/mp2/maze.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * tab:4 - * - * maze.h - maze generation and display header file - * - * "Copyright (c) 2004-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 2 - * Creation Date: Thu Sep 9 22:09:54 2004 - * Filename: maze.h - * History: - * SL 1 Thu Sep 9 22:09:54 2004 - * First written. - * SL 2 Sat Sep 12 14:01:15 2009 - * Integrated original release back into main code base. - */ - -#ifndef MAZE_H -#define MAZE_H - -#include "blocks.h" -#include "modex.h" - -#define SHOW_MIN 6 /* hide the last six pixels of boundary */ - -/* - * Define maze minimum and maximum dimensions. The description of make_maze - * in maze.c gives details on the layout of the maze. Minimum values are - * chosen to ensure that a maze fills the scrolling region of the screen. - * Maximum values are somewhat arbitrary. - */ -#define MAZE_MIN_X_DIM ((SCROLL_X_DIM + (BLOCK_X_DIM - 1) + 2 * SHOW_MIN) / (2 * BLOCK_X_DIM)) -#define MAZE_MAX_X_DIM 50 -#define MAZE_MIN_Y_DIM ((SCROLL_Y_DIM + (BLOCK_Y_DIM - 1) + 2 * SHOW_MIN) / (2 * BLOCK_Y_DIM)) -#define MAZE_MAX_Y_DIM 30 - -/* bit vector of properties for spaces in the maze */ -typedef enum { - MAZE_NONE = 0, /* empty */ - MAZE_WALL = 1, /* wall */ - MAZE_FRUIT_1 = 2, /* fruit (3-bit field, with 0 for no fruit) */ - MAZE_FRUIT_2 = 4, - MAZE_FRUIT_3 = 8, - LAST_MAZE_FRUIT_BIT = MAZE_FRUIT_3, - MAZE_FRUIT = (MAZE_FRUIT_1 | MAZE_FRUIT_2 | MAZE_FRUIT_3), - MAZE_EXIT = 16, /* exit from maze */ - MAZE_REACH = 128 /* seen already (not shrouded in mist) */ -} maze_bit_t; - -/* create a maze and place some fruits inside it */ -extern int make_maze(int x_dim, int y_dim, int start_fruits); - -/* fill a buffer with the pixels for a horizontal line of the maze */ -extern void fill_horiz_buffer(int x, int y, unsigned char buf[SCROLL_X_DIM]); - -/* fill a buffer with the pixels for a vertical line of the maze */ -extern void fill_vert_buffer(int x, int y, unsigned char buf[SCROLL_Y_DIM]); - -/* mark a maze location as reached and draw it onto the screen if necessary */ -extern void unveil_space(int x, int y); - -/* consume fruit at a space, if any; returns the fruit number consumed */ -extern int check_for_fruit(int x, int y); - -/* check whether the player has reached the exit with no fruits left */ -extern int check_for_win(int x, int y); - -/* add a new fruit randomly in the maze */ -extern int add_a_fruit(); - -/* get pointer to the player's block image; depends on direction of motion */ -extern unsigned char* get_player_block(dir_t cur_dir); - -/* get pointer to the player's mask image; depends on direction of motion */ -extern unsigned char* get_player_mask(dir_t cur_dir); - -/* determine which directions are open to movement from a given maze point */ -extern void find_open_directions(int x, int y, int op[NUM_DIRS]); - -/* get number of fruit exist*/ -extern int get_fruit_num(); - -#endif /* MAZE_H */ diff --git a/mp2/mazegame-demo b/mp2/mazegame-demo deleted file mode 100644 index c864f4f..0000000 Binary files a/mp2/mazegame-demo and /dev/null differ diff --git a/mp2/mazegame.c b/mp2/mazegame.c deleted file mode 100644 index 610f409..0000000 --- a/mp2/mazegame.c +++ /dev/null @@ -1,888 +0,0 @@ -/* - * tab:4 - * - * mazegame.c - main source file for ECE398SSL maze game (F04 MP2) - * - * "Copyright (c) 2004 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 1 - * Creation Date: Fri Sep 10 09:57:54 2004 - * Filename: mazegame.c - * History: - * SL 1 Fri Sep 10 09:57:54 2004 - * First written. - */ - -#include -#include -#include - -#include "blocks.h" -#include "maze.h" -#include "modex.h" -#include "text.h" - -#include "module/tuxctl-ioctl.h" - -// New Includes and Defines -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BACKQUOTE 96 -#define UP 65 -#define DOWN 66 -#define RIGHT 67 -#define LEFT 68 -#define BLK_SIZE 144 -#define LEVEL 10 /* maximum level */ - -/* - * If NDEBUG is not defined, we execute sanity checks to make sure that - * changes to enumerations, bit maps, etc., have been made consistently. - */ -#if defined(NDEBUG) -#define sanity_check() 0 -#else -static int sanity_check(); -#endif - - -int fruit_type; /* variable to distinguish fruit type */ -int got_fruit_timer; /* timer to determine when fruit disappears */ -//int tux_time; -/* a few constants */ -#define PAN_BORDER 5 /* pan when border in maze squares reaches 5 */ -#define MAX_LEVEL 10 /* maximum level number */ - -/* outcome of each level, and of the game as a whole */ -typedef enum {GAME_WON, GAME_LOST, GAME_QUIT} game_condition_t; - -/* structure used to hold game information */ -typedef struct { - /* parameters varying by level */ - int number; /* starts at 1... */ - int maze_x_dim, maze_y_dim; /* min to max, in steps of 2 */ - int initial_fruit_count; /* 1 to 6, in steps of 1/2 */ - int time_to_first_fruit; /* 300 to 120, in steps of -30 */ - int time_between_fruits; /* 300 to 60, in steps of -30 */ - int tick_usec; /* 20000 to 5000, in steps of -1750 */ - - /* dynamic values within a level -- you may want to add more... */ - unsigned int map_x, map_y; /* current upper left display pixel */ -} game_info_t; - -static game_info_t game_info; - -/* local functions--see function headers for details */ -static int prepare_maze_level(int level); -static void move_up(int* ypos); -static void move_right(int* xpos); -static void move_down(int* ypos); -static void move_left(int* xpos); -static int unveil_around_player(int play_x, int play_y); -static void *rtc_thread(void *arg); -static void *keyboard_thread(void *arg); - -static void *tux_thread(void *arg); -static void show_time(); -/* - * prepare_maze_level - * DESCRIPTION: Prepare for a maze of a given level. Fills the game_info - * structure, creates a maze, and initializes the display. - * INPUTS: level -- level to be used for selecting parameter values - * OUTPUTS: nonef - * RETURN VALUE: 0 on success, -1 on failure - * SIDE EFFECTS: writes entire game_info structure; changes maze; - * initializes display - */ -static int prepare_maze_level(int level) { - int i; /* loop index for drawing display */ - - /* - * Record level in game_info; other calculations use offset from - * level 1. - */ - game_info.number = level--; - - /* Set per-level parameter values. */ - if ((game_info.maze_x_dim = MAZE_MIN_X_DIM + 2 * level) > MAZE_MAX_X_DIM) - game_info.maze_x_dim = MAZE_MAX_X_DIM; - if ((game_info.maze_y_dim = MAZE_MIN_Y_DIM + 2 * level) > MAZE_MAX_Y_DIM) - game_info.maze_y_dim = MAZE_MAX_Y_DIM; - if ((game_info.initial_fruit_count = 1 + level / 2) > 6) - game_info.initial_fruit_count = 6; - if ((game_info.time_to_first_fruit = 300 - 30 * level) < 120) - game_info.time_to_first_fruit = 120; - if ((game_info.time_between_fruits = 300 - 60 * level) < 60) - game_info.time_between_fruits = 60; - if ((game_info.tick_usec = 20000 - 1750 * level) < 5000) - game_info.tick_usec = 5000; - - /* Initialize dynamic values. */ - game_info.map_x = game_info.map_y = SHOW_MIN; - - /* Create a maze. */ - if (make_maze(game_info.maze_x_dim, game_info.maze_y_dim, game_info.initial_fruit_count) != 0) - return -1; - - /* Set logical view and draw initial screen. */ - set_view_window(game_info.map_x, game_info.map_y); - for (i = 0; i < SCROLL_Y_DIM; i++) - (void)draw_horiz_line (i); - - /* Return success. */ - return 0; -} - -/* - * move_up - * DESCRIPTION: Move the player up one pixel (assumed to be a legal move) - * INPUTS: ypos -- pointer to player's y position (pixel) in the maze - * OUTPUTS: *ypos -- reduced by one from initial value - * RETURN VALUE: none - * SIDE EFFECTS: pans display by one pixel when appropriate - */ -static void move_up(int* ypos) { - /* - * Move player by one pixel and check whether display should be panned. - * Panning is necessary when the player moves past the upper pan border - * while the top pixels of the maze are not on-screen. - */ - if (--(*ypos) < game_info.map_y + BLOCK_Y_DIM * PAN_BORDER && game_info.map_y > SHOW_MIN) { - /* - * Shift the logical view upwards by one pixel and draw the - * new line. - */ - set_view_window(game_info.map_x, --game_info.map_y); - (void)draw_horiz_line(0); - } -} - -/* - * move_right - * DESCRIPTION: Move the player right one pixel (assumed to be a legal move) - * INPUTS: xpos -- pointer to player's x position (pixel) in the maze - * OUTPUTS: *xpos -- increased by one from initial value - * RETURN VALUE: none - * SIDE EFFECTS: pans display by one pixel when appropriate - */ -static void move_right(int* xpos) { - /* - * Move player by one pixel and check whether display should be panned. - * Panning is necessary when the player moves past the right pan border - * while the rightmost pixels of the maze are not on-screen. - */ - if (++(*xpos) > game_info.map_x + SCROLL_X_DIM - BLOCK_X_DIM * (PAN_BORDER + 1) && - game_info.map_x + SCROLL_X_DIM < (2 * game_info.maze_x_dim + 1) * BLOCK_X_DIM - SHOW_MIN) { - /* - * Shift the logical view to the right by one pixel and draw the - * new line. - */ - set_view_window(++game_info.map_x, game_info.map_y); - (void)draw_vert_line(SCROLL_X_DIM - 1); - } -} - -/* - * move_down - * DESCRIPTION: Move the player right one pixel (assumed to be a legal move) - * INPUTS: ypos -- pointer to player's y position (pixel) in the maze - * OUTPUTS: *ypos -- increased by one from initial value - * RETURN VALUE: none - * SIDE EFFECTS: pans display by one pixel when appropriate - */ -static void move_down(int* ypos) { - /* - * Move player by one pixel and check whether display should be panned. - * Panning is necessary when the player moves past the right pan border - * while the bottom pixels of the maze are not on-screen. - */ - if (++(*ypos) > game_info.map_y + SCROLL_Y_DIM - BLOCK_Y_DIM * (PAN_BORDER + 1) && - game_info.map_y + SCROLL_Y_DIM < (2 * game_info.maze_y_dim + 1) * BLOCK_Y_DIM - SHOW_MIN) { - /* - * Shift the logical view downwards by one pixel and draw the - * new line. - */ - set_view_window(game_info.map_x, ++game_info.map_y); - (void)draw_horiz_line(SCROLL_Y_DIM - 1); - } -} - -/* - * move_left - * DESCRIPTION: Move the player right one pixel (assumed to be a legal move) - * INPUTS: xpos -- pointer to player's x position (pixel) in the maze - * OUTPUTS: *xpos -- decreased by one from initial value - * RETURN VALUE: none - * SIDE EFFECTS: pans display by one pixel when appropriate - */ -static void move_left(int* xpos) { - /* - * Move player by one pixel and check whether display should be panned. - * Panning is necessary when the player moves past the left pan border - * while the leftmost pixels of the maze are not on-screen. - */ - if (--(*xpos) < game_info.map_x + BLOCK_X_DIM * PAN_BORDER && game_info.map_x > SHOW_MIN) { - /* - * Shift the logical view to the left by one pixel and draw the - * new line. - */ - set_view_window(--game_info.map_x, game_info.map_y); - (void)draw_vert_line (0); - } -} - -/* - * unveil_around_player - * DESCRIPTION: Show the maze squares in an area around the player. - * Consume any fruit under the player. Check whether - * player has won the maze level. - * INPUTS: (play_x,play_y) -- player coordinates in pixels - * OUTPUTS: none - * RETURN VALUE: 1 if player wins the level by entering the square - * 0 if not - * SIDE EFFECTS: draws maze squares for newly visible maze blocks, - * consumed fruit, and maze exit; consumes fruit and - * updates dFsetisplayed fruit counts - */ -static int unveil_around_player(int play_x, int play_y) { - int x = play_x / BLOCK_X_DIM; /* player's maze lattice position */ - int y = play_y / BLOCK_Y_DIM; - int i, j; /* loop indices for unveiling maze squares */ - - /* Check for fruit at the player's position. */ - fruit_type = check_for_fruit (x, y); - - if(fruit_type !=0){ - got_fruit_timer = 128; - } - /* Unveil spaces around the player. */ - for (i = -1; i < 2; i++) - for (j = -1; j < 2; j++) - unveil_space(x + i, y + j); - unveil_space(x, y - 2); - unveil_space(x + 2, y); - unveil_space(x, y + 2); - unveil_space(x - 2, y); - - /* Check whether the player has won the maze level. */ - return check_for_win (x, y); -} - -#ifndef NDEBUG -/* - * sanity_check - * DESCRIPTION: Perform checks on changes to constants and enumerated values. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: 0 if checks pass, -1 if any fail - * SIDE EFFECTS: none - */ -static int sanity_check() { - /* - * Automatically detect when fruits have been added in blocks.h - * without allocating enough bits to identify all types of fruit - * uniquely (along with 0, which means no fruit). - */ - if (((2 * LAST_MAZE_FRUIT_BIT) / MAZE_FRUIT_1) < NUM_FRUIT_TYPES + 1) { - puts("You need to allocate more bits in maze_bit_t to encode fruit."); - return -1; - } - return 0; -} -#endif /* !defined(NDEBUG) */ - -// Shared Global Variables -int quit_flag = 0; -int winner= 0; -int next_dir = UP; -int play_x, play_y, last_dir, dir; -int move_cnt = 0; -int fd; -int ft; -unsigned long data; -static struct termios tio_orig; -static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; - -/* condition variable to prevent delay */ -static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; - -int buttons_pressed =0 ; /* shared variable to determine whether button is pressed or not */ -unsigned char directions; /* shared variable to determine direction */ - - - -/* - * tux_thread - * DESCRIPTION: Thread that handles TUX INPUTS - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void *tux_thread(void *arg){ - while(winner == 0){ - if(quit_flag == 1){ - break; - } - - pthread_mutex_lock(&mtx); - - /* if button is not pressed, release the lock and wait for condition varibale signal */ - while(!buttons_pressed){ - pthread_cond_wait(&cv, &mtx); - } - - switch(directions){ - case TUX_BUTTON_LEFT: - next_dir = DIR_LEFT; - break; - case TUX_BUTTON_DOWN: - next_dir = DIR_DOWN; - break; - case TUX_BUTTON_RIGHT: - next_dir = DIR_RIGHT; - break; - case TUX_BUTTON_UP: - next_dir = DIR_UP; - break; - default: - break; - } - pthread_mutex_unlock(&mtx); - } - return 0; -} - - -/* - * show_time - * DESCRIPTION: convert time to send data to TUX LED to be displayed - * INPUTS: t -- time to be displayed on TUX LED - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void show_time(int t){ - unsigned long tux_time = t; - unsigned long led_input = DEFAULT_LED_VALUE; /* 0X040F0000 */ - - unsigned long second = tux_time % 60; /* seconds */ - unsigned long second1 = second % 10; /* 1st */ - unsigned long second10 = second / 10; /* 10th */ - - unsigned long minute = tux_time / 60; /* minutes */ - unsigned long minute1 = minute % 10; /* 1st */ - unsigned long minute10 = minute / 10; /* 10th */ - - - /* shift bits to put them in right position */ - led_input = led_input | (minute10 << 12); - led_input = led_input | (minute1 << 8); - led_input = led_input | (second10 << 4); - led_input = led_input | second1; - - //if( t % 32 == 0){ - ioctl(ft,TUX_SET_LED,led_input); - //} - -} - -/* - * keyboard_thread - * DESCRIPTION: Thread that handles keyboard inputs - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void *keyboard_thread(void *arg) { - char key; - int state = 0; - // Break only on win or quit input - '`' - while (winner == 0) { - // Get Keyboard Input - key = getc(stdin); - - // Check for '`' to quit - if (key == BACKQUOTE) { - quit_flag = 1; - break; - } - - // Compare and Set next_dir - // Arrow keys deliver 27, 91, ## - if (key == 27) { - state = 1; - } - else if (key == 91 && state == 1) { - state = 2; - } - else { - if (key >= UP && key <= LEFT && state == 2) { - pthread_mutex_lock(&mtx); - switch(key) { - case UP: - //if(!buttons_pressed){ /* prioritize TUX */ - next_dir = DIR_UP; - //} - break; - case DOWN: - //if(!buttons_pressed){ /* prioritize TUX */ - next_dir = DIR_DOWN; - //} - break; - case RIGHT: - //if(!buttons_pressed){ /* prioritize TUX */ - next_dir = DIR_RIGHT; - //} - break; - case LEFT: - //if(!buttons_pressed){ /* prioritize TUX */ - next_dir = DIR_LEFT; - //} - break; - } - pthread_mutex_unlock(&mtx); - } - state = 0; - } - } - - return 0; -} - -/* some stats about how often we take longer than a single timer tick */ -static int goodcount = 0; -static int badcount = 0; -static int total = 0; - -/* - * rtc_thread - * DESCRIPTION: Thread that handles updating the screen - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void *rtc_thread(void *arg) { - int ticks = 0; - int level; - int ret; - int open[NUM_DIRS]; - int goto_next_level = 0; - int color_idx =0; - int n_fruits; /* constant to keep track of number of fruits*/ - int time=0; /* constant to keep track of time*/ - int time_refresh = 0; /* constant used to refesh time when level is changed*/ - unsigned char old_block_buffer[BLK_SIZE]; /* buffer to save the old background of the block to draw on */ - int xbuffer =0; /* old x position holder */ - int ybuffer =0; /* old y position holder */ - - int head_idx =0; /* index to change color on player's head */ - int head_cycle =0; /* cycle time to change color on player's head */ - - int fruit_xbuffer=0; /* buffer to hold x coordinate where string will be drawn */ - int fruit_ybuffer =0; /* buffer to hold y coordinate where string will be drawn */ - int old_fruit_xbuffer=0; /* buffer to hold old x coordinate where string will be drawn */ - int old_fruit_ybuffer=0; /* buffer to hold old y coordinate where string will be drawn */ - - - unsigned char old_fruit_buffer[TXT_X_DIM*TXT_Y_DIM]; /* buffer that holds background data TXT_X_DIM by TXT_Y_DIM */ - unsigned char fruit_txt_buffer[TXT_X_DIM*TXT_Y_DIM]; /* buffer that holds string data drawn on TXT_X_DIM by TXT_Y_DIM image */ - - unsigned char tr; /* transparent r value */ - unsigned char tg; /* transparent g value */ - unsigned char tb; /* transparent b value */ - - char* fruit; /* pointer to string data to be drawn */ - - - - /* buffer that holds strings data */ - char* fruit_txt[NUM_FRUITS] ={"an apple!", "a grape!","a peach!","a strawberry!","a banana!","a watermelon!","a Dew!"}; - - /* buffer that holds color value for status bar */ - int status_bar_colors[LEVEL] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A}; - - /* buffer that holds r values that will change per level */ - int r[LEVEL] ={0x3F,0x0A,0x00,0x0F,0x00,0x3E,0x07,0x08,0x09,0x3F}; - /* buffer that holds g values that will change per level */ - int g[LEVEL] ={0x00,0x0A,0x3F,0x07,0x00,0x0F,0x1F,0x3E,0x0A,0x03}; - /* buffer that holds b values that will change per level */ - int b[LEVEL] ={0x00,0x0A,0x00,0x0A,0x3F,0x0F,0x03,0x04,0x3F,0x06}; - - - // Loop over levels until a level is lost or quit. - for (level = 1; (level <= MAX_LEVEL) && (quit_flag == 0); level++) { - // Prepare for the level. If we fail, just let the player win. - if (prepare_maze_level(level) != 0) - break; - goto_next_level = 0; - - // Start the player at (1,1) - play_x = BLOCK_X_DIM; - play_y = BLOCK_Y_DIM; - - // move_cnt tracks moves remaining between maze squares. - // When not moving, it should be 0. - move_cnt = 0; - - // Initialize last direction moved to up - last_dir = DIR_UP; - - // Initialize the current direction of motion to stopped - dir = DIR_STOP; - next_dir = DIR_STOP; - - /* change color palette where WALL WALL FILL depends on current level */ - color_idx = level-1; - //set_palette_colors(WALL_OUTLINE_COLOR,r[color_idx],g[color_idx],b[color_idx]); - set_palette_colors(WALL_FILL_COLOR,r[color_idx],g[color_idx],b[color_idx]); - - /* calculate transparent color and change color palette */ - tr = (r[color_idx] + WHITE)/2; - tg = (g[color_idx] + WHITE)/2; - tb = (b[color_idx] + WHITE)/2; - - //set_palette_colors(WALL_OUTLINE_COLOR+0x40,tr,tg,tb); - set_palette_colors(WALL_FILL_COLOR+T_OFFSET,tr,tg,tb); - - - // Show maze around the player's original position - (void)unveil_around_player(play_x, play_y); - - /*store old position of the player*/ - xbuffer = play_x; - ybuffer = play_y; - - // get first Periodic Interrupt - ret = read(fd, &data, sizeof(unsigned long)); - - while ((quit_flag == 0) && (goto_next_level == 0)) { - // Wait for Periodic Interrupt - ret = read(fd, &data, sizeof(unsigned long)); - - - /* execute show_time every second to prevent spamming */ - - - // Update tick to keep track of time. If we missed some - // interrupts we want to update the player multiple times so - // that player velocity is smooth - ticks = data >> 8; - - total += ticks; - time_refresh +=ticks; - - /* change head color every half a second for 10 cycles*/ - head_cycle = time_refresh/HALF_SEC; - head_idx = head_cycle % NUM_HEAD_CYCLES; - show_status_bar(level, n_fruits,time,status_bar_colors[level]); - - set_palette_colors(PLAYER_CENTER_COLOR,g[head_idx],b[head_idx],r[head_idx]); - tr = (r[color_idx] + WHITE)/2; - tg = (g[color_idx] + WHITE)/2; - tb = (b[color_idx] + WHITE)/2; - set_palette_colors(PLAYER_CENTER_COLOR+0x40,tg,tb,tr); - - - time = time_refresh / SEC; - /* prevent spamming */ - if(time_refresh % SEC < 2){ - show_time(time); - } - - n_fruits = get_fruit_num(); - - // If the system is completely overwhelmed we better slow down: - if (ticks > 8) ticks = 8; - - if (ticks > 1) { - badcount++; - } - else { - goodcount++; - } - - unsigned long buttons; - while (ticks--) { - - // Lock the mutex - //pthread_mutex_lock(&mtx); - - ioctl(ft,TUX_BUTTONS, &buttons); - directions = buttons & 0xFF; - - if(directions != 0xFF){ - buttons_pressed = 1; - }else{ - buttons_pressed = 0; - } - - pthread_mutex_lock(&mtx); - - /* if button is pressed, send signal to cv */ - if(buttons_pressed){ - pthread_cond_signal(&cv); - } - pthread_mutex_unlock(&mtx); - - pthread_mutex_lock(&mtx); - // Check to see if a key has been pressed - if (next_dir != dir) { - // Check if new direction is backwards...if so, do immediately - if ((dir == DIR_UP && next_dir == DIR_DOWN) || - (dir == DIR_DOWN && next_dir == DIR_UP) || - (dir == DIR_LEFT && next_dir == DIR_RIGHT) || - (dir == DIR_RIGHT && next_dir == DIR_LEFT)) { - if (move_cnt > 0) { - if (dir == DIR_UP || dir == DIR_DOWN) - move_cnt = BLOCK_Y_DIM - move_cnt; - else - move_cnt = BLOCK_X_DIM - move_cnt; - } - dir = next_dir; - } - } - - // New Maze Square! - if (move_cnt == 0) { - // The player has reached a new maze square; unveil nearby maze - // squares and check whether the player has won the level. - if (unveil_around_player(play_x, play_y)) { - pthread_mutex_unlock(&mtx); - goto_next_level = 1; - time_refresh = 0; - got_fruit_timer =0; - break; - } - - // Record directions open to motion. - find_open_directions (play_x / BLOCK_X_DIM, play_y / BLOCK_Y_DIM, open); - - // Change dir to next_dir if next_dir is open - if (open[next_dir]) { - dir = next_dir; - } - - // The direction may not be open to motion... - // 1) ran into a wall - // 2) initial direction and its opposite both face walls - if (dir != DIR_STOP) { - if (!open[dir]) { - dir = DIR_STOP; - } - else if (dir == DIR_UP || dir == DIR_DOWN) { - move_cnt = BLOCK_Y_DIM; - } - else { - move_cnt = BLOCK_X_DIM; - } - } - } - - // Unlock the mutex - pthread_mutex_unlock(&mtx); - - if (dir != DIR_STOP) { - // move in chosen direction - last_dir = dir; - move_cnt--; - switch (dir) { - case DIR_UP: - move_up(&play_y); - break; - case DIR_RIGHT: - move_right(&play_x); - break; - case DIR_DOWN: - move_down(&play_y); - break; - case DIR_LEFT: - move_left(&play_x); - break; - } - - } - } - - - /* save location of blocks to copy */ - xbuffer = play_x; - ybuffer = play_y; - - /*draw masked player image on the address*/ - draw_mask(play_x,play_y,get_player_mask(last_dir), get_player_block(last_dir), old_block_buffer); - - /* save location where string will be drawn */ - fruit_xbuffer = play_x - TXT_X_OFFSET; - fruit_ybuffer = play_y - TXT_Y_DIM; - - /* check if player got fruit, save it to fruit if it did */ - if(fruit_type !=0){ - fruit = fruit_txt[fruit_type-1]; - } - /* if player got the fruit, start draw procedure*/ - if(got_fruit_timer > 0){ - - /* prevent string from going out of top frame */ - if(fruit_ybuffer <= TXT_Y_LIMIT){ - fruit_ybuffer = TXT_Y_LIMIT; - } - - /* save the old string location */ - old_fruit_xbuffer = fruit_xbuffer; - old_fruit_ybuffer = fruit_ybuffer; - - /* save block of image to old_fruit_buffer and fruit_txt_buffer */ - draw_fruit_txt(fruit_xbuffer, fruit_ybuffer, old_fruit_buffer,fruit_txt_buffer); - /* write string to fruit_txt_buffer*/ - string_to_buf_fruit(fruit,fruit_txt_buffer); - /* draw fruit_txt_buffer which contains txt to vga buffer */ - draw_string(fruit_xbuffer,fruit_ybuffer,fruit_txt_buffer); - - } - /* show it to screen */ - show_screen(); - - /* cover the string image with old background and decrement fruit timer */ - if(got_fruit_timer > 0){ - draw_string(old_fruit_xbuffer,old_fruit_ybuffer,old_fruit_buffer); - got_fruit_timer--; - } - - /*cover the player image with old background image*/ - draw_full_block(xbuffer, ybuffer, old_block_buffer); - } - } - if (quit_flag == 0) - winner = 1; - - return 0; -} - - -/* - * main - * DESCRIPTION: Initializes and runs the two threads - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: 0 on success, -1 on failure - * SIDE EFFECTS: none - */ -int main() { - int ret; - struct termios tio_new; - unsigned long update_rate = 32; /* in Hz */ - - pthread_t tid1; - pthread_t tid2; - pthread_t tid3; //tux_thread - - // Initialize RTC - fd = open("/dev/rtc", O_RDONLY, 0); - - ft = open("/dev/ttyS0", O_RDWR | O_NOCTTY); - int ldisc_num = N_MOUSE; - ioctl(ft, TIOCSETD, &ldisc_num); - ioctl(ft, TUX_INIT,0); - - // Enable RTC periodic interrupts at update_rate Hz - // Default max is 64...must change in /proc/sys/dev/rtc/max-user-freq - ret = ioctl(fd, RTC_IRQP_SET, update_rate); - ret = ioctl(fd, RTC_PIE_ON, 0); - - // Initialize Keyboard - // Turn on non-blocking mode - if (fcntl(fileno(stdin), F_SETFL, O_NONBLOCK) != 0) { - perror("fcntl to make stdin non-blocking"); - return -1; - } - - // Save current terminal attributes for stdin. - if (tcgetattr(fileno(stdin), &tio_orig) != 0) { - perror("tcgetattr to read stdin terminal settings"); - return -1; - } - - // Turn off canonical (line-buffered) mode and echoing of keystrokes - // Set minimal character and timing parameters so as - tio_new = tio_orig; - tio_new.c_lflag &= ~(ICANON | ECHO); - tio_new.c_cc[VMIN] = 1; - tio_new.c_cc[VTIME] = 0; - if (tcsetattr(fileno(stdin), TCSANOW, &tio_new) != 0) { - perror("tcsetattr to set stdin terminal settings"); - return -1; - } - - // Perform Sanity Checks and then initialize input and display - if ((sanity_check() != 0) || (set_mode_X(fill_horiz_buffer, fill_vert_buffer) != 0)){ - return 3; - } - - // Create the threads - pthread_create(&tid1, NULL, rtc_thread, NULL); - pthread_create(&tid2, NULL, keyboard_thread, NULL); - pthread_create(&tid3, NULL, tux_thread, NULL); - - - // Wait for all the threads to end - pthread_join(tid1, NULL); - pthread_join(tid2, NULL); - pthread_cancel(tid3); /* terminate TUX thread */ - - // Shutdown Display - clear_mode_X(); - - // Close Keyboard - (void)tcsetattr(fileno(stdin), TCSANOW, &tio_orig); - - // Close RTC - close(fd); - - // close tux - close(ft); - - // Print outcome of the game - if (winner == 1) { - printf("You win the game! CONGRATULATIONS!\n"); - } - else if (quit_flag == 1) { - printf("Quitter!\n"); - } - else { - printf ("Sorry, you lose...\n"); - } - - // Return success - return 0; -} diff --git a/mp2/modex.c b/mp2/modex.c deleted file mode 100644 index 5db67c1..0000000 --- a/mp2/modex.c +++ /dev/null @@ -1,1417 +0,0 @@ -/* - * tab:4 - * - * modex.c - VGA mode X graphics routines - * - * "Copyright (c) 2004-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 3 - * Creation Date: Fri Sep 10 09:59:17 2004 - * Filename: modex.c - * History: - * SL 1 Fri Sep 10 09:59:17 2004 - * First written. - * SL 2 Sat Sep 12 16:41:45 2009 - * Integrated original release back into main code base. - * SL 3 Sat Sep 12 17:58:20 2009 - * Added display re-enable to VGA blank routine and comments - * on other VirtualPC->QEMU migration changes. - */ -#include -#include -#include -#include -#include -#include - -#include "blocks.h" -#include "modex.h" -#include "text.h" - -/* - * Calculate the image build buffer parameters. SCROLL_SIZE is the space - * needed for one plane of an image. SCREEN_SIZE is the space needed for - * all four planes. The extra +1 supports logical view x coordinates that - * are not multiples of four. In these cases, some plane addresses are - * shifted by 1 byte forward. The planes are stored in the build buffer - * in reverse order to allow those planes that shift forward to do so - * without running into planes that aren't shifted. For example, when - * the leftmost x pixel in the logical view is 3 mod 4, planes 2, 1, and 0 - * are shifted forward, while plane 3 is not, so there is one unused byte - * between the image of plane 3 and that of plane 2. BUILD_BUF_SIZE is - * the size of the space allocated for building images. We add 20000 bytes - * to reduce the number of memory copies required during scrolling. - * Strictly speaking (try it), no extra space is necessary, but the minimum - * means an extra 64kB memory copy with every scroll pixel. Finally, - * BUILD_BASE_INIT places initial (or transferred) logical view in the - * middle of the available buffer area. - */ -#define SCROLL_SIZE (SCROLL_X_WIDTH * SCROLL_Y_DIM) -#define SCREEN_SIZE (SCROLL_SIZE * 4 + 1) -#define BUILD_BUF_SIZE (SCREEN_SIZE + 20000) -#define BUILD_BASE_INIT ((BUILD_BUF_SIZE - SCREEN_SIZE) / 2) - -/* Mode X and general VGA parameters */ -#define VID_MEM_SIZE 131072 -#define MODE_X_MEM_SIZE 65536 -#define NUM_SEQUENCER_REGS 5 -#define NUM_CRTC_REGS 25 -#define NUM_GRAPHICS_REGS 9 -#define NUM_ATTR_REGS 22 - -#define STATUS_PLANE_SIZE (STATUS_X_WIDTH * STATUS_Y_DIM) //1440 -#define STATUS_SCREEN_SIZE (STATUS_PLANE_SIZE * 4) //5760 -#define MAX_STRING (STATUS_X_DIM / 8) //40 - -/* VGA register settings for mode X */ -static unsigned short mode_X_seq[NUM_SEQUENCER_REGS] = { - 0x0100, 0x2101, 0x0F02, 0x0003, 0x0604 -}; - -//Line Compare Register(18h) -//Overflow Register(7h) #bit 4 = LCR #8 -//Maximum Scan Line Register(09h) #bit 6 = LCR #9 - -//change those bit values to 182*2-1 =363 = 0x16B -static unsigned short mode_X_CRTC[NUM_CRTC_REGS] = { - 0x5F00, 0x4F01, 0x5002, 0x8203, 0x5404, 0x8005, 0xBF06, 0x1F07, - 0x0008, 0x0109, 0x000A, 0x000B, 0x000C, 0xB50D, 0x000E, 0x000F, - 0x9C10, 0x8E11, 0x8F12, 0x2813, 0x0014, 0x9615, 0xB916, 0xE317, - 0x6B18 -}; - -//set Pixel Planning Mode in Attribute Mode Control Reg (10h) bit #5 from 0 to 1 -//0x41 -> 0x61 for immobile status bar (disable shifts) (as if Byte panning and Pixel Shift Count are set to 0) -static unsigned char mode_X_attr[NUM_ATTR_REGS * 2] = { - 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, - 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, - 0x08, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, - 0x0C, 0x0C, 0x0D, 0x0D, 0x0E, 0x0E, 0x0F, 0x0F, - 0x10, 0x61, 0x11, 0x00, 0x12, 0x0F, 0x13, 0x00, - 0x14, 0x00, 0x15, 0x00 -}; -static unsigned short mode_X_graphics[NUM_GRAPHICS_REGS] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x4005, 0x0506, 0x0F07, - 0xFF08 -}; - -/* VGA register settings for text mode 3 (color text) */ -static unsigned short text_seq[NUM_SEQUENCER_REGS] = { - 0x0100, 0x2001, 0x0302, 0x0003, 0x0204 -}; -static unsigned short text_CRTC[NUM_CRTC_REGS] = { - 0x5F00, 0x4F01, 0x5002, 0x8203, 0x5504, 0x8105, 0xBF06, 0x1F07, - 0x0008, 0x4F09, 0x0D0A, 0x0E0B, 0x000C, 0x000D, 0x000E, 0x000F, - 0x9C10, 0x8E11, 0x8F12, 0x2813, 0x1F14, 0x9615, 0xB916, 0xA317, - 0xFF18 -}; -static unsigned char text_attr[NUM_ATTR_REGS * 2] = { - 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, - 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, - 0x08, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, - 0x0C, 0x0C, 0x0D, 0x0D, 0x0E, 0x0E, 0x0F, 0x0F, - 0x10, 0x0C, 0x11, 0x00, 0x12, 0x0F, 0x13, 0x08, - 0x14, 0x00, 0x15, 0x00 -}; -static unsigned short text_graphics[NUM_GRAPHICS_REGS] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x1005, 0x0E06, 0x0007, - 0xFF08 -}; - -/* local functions--see function headers for details */ -static int open_memory_and_ports(); -static void VGA_blank(int blank_bit); -static void set_seq_regs_and_reset(unsigned short table[NUM_SEQUENCER_REGS], unsigned char val); -static void set_CRTC_registers(unsigned short table[NUM_CRTC_REGS]); -static void set_attr_registers(unsigned char table[NUM_ATTR_REGS * 2]); -static void set_graphics_registers(unsigned short table[NUM_GRAPHICS_REGS]); -static void fill_palette(); -static void write_font_data(); -static void set_text_mode_3(int clear_scr); -static void copy_image(unsigned char* img, unsigned short scr_addr); -static void copy_status_bar(unsigned char* img, unsigned short scr_addr); -/* - * Images are built in this buffer, then copied to the video memory. - * Copying to video memory with REP MOVSB is vastly faster than anything - * else with emulation, probably because it is a single instruction - * and translates to a native loop. It's also a pretty good technique - * in normal machines (albeit not as elegant as some others for reducing - * the number of video memory writes; unfortunately, these techniques - * are slower in emulation...). - * - * The size allows the four plane images to move within an area of - * about twice the size necessary (to reduce the need to deal with - * the boundary conditions by moving the data within the buffer). - * - * Plane 3 is first, followed by 2, 1, and 0. The reverse ordering - * is used because the logical address of 0 increases first; if plane - * 0 were first, we would need a buffer byte to keep it from colliding - * with plane 1 when plane 0 was offset by 1 from plane 1, i.e., when - * displaying a one-pixel left shift. - * - * The memory fence (included when NDEBUG is not defined) allocates - * the build buffer with extra space on each side. The extra space - * is filled with magic numbers (something unlikely to be written in - * error), and the fence areas are checked for those magic values at - * the end of the program to detect array access bugs (writes past - * the ends of the build buffer). - */ -#ifndef NDEBUG -#define MEM_FENCE_WIDTH 256 -#else -#define MEM_FENCE_WIDTH 0 -#endif -#define MEM_FENCE_MAGIC 0xF3 - -static unsigned char build[BUILD_BUF_SIZE + 2 * MEM_FENCE_WIDTH]; -static int img3_off; /* offset of upper left pixel */ -static unsigned char* img3; /* pointer to upper left pixel */ -static int show_x, show_y; /* logical view coordinates */ - - /* displayed video memory variables */ -static unsigned char* mem_image; /* pointer to start of video memory */ -static unsigned short target_img; /* offset of displayed screen image */ - -/* - * functions provided by the caller to set_mode_X() and used to obtain - * graphic images of lines (pixels) to be mapped into the build buffer - * planes for display in mode X - */ -static void (*horiz_line_fn)(int, int, unsigned char[SCROLL_X_DIM]); -static void (*vert_line_fn)(int, int, unsigned char[SCROLL_Y_DIM]); - -/* - * macro used to target a specific video plane or planes when writing - * to video memory in mode X; bits 8-11 in the mask_hi_bits enable writes - * to planes 0-3, respectively - */ -#define SET_WRITE_MASK(mask_hi_bits) \ -do { \ - asm volatile (" \n\ - movw $0x03C4, %%dx /* set write mask */ \n\ - movb $0x02, %b0 \n\ - outw %w0, (%%dx) \n\ - " \ - : /* no outputs */ \ - : "a"((mask_hi_bits)) \ - : "edx", "memory" \ - ); \ -} while (0) - -/* macro used to write a byte to a port */ -#define OUTB(port, val) \ -do { \ - asm volatile ("outb %b1, (%w0)" \ - : /* no outputs */ \ - : "d"((port)), "a"((val)) \ - : "memory", "cc" \ - ); \ -} while (0) - -/* macro used to write two bytes to two consecutive ports */ -#define OUTW(port, val) \ -do { \ - asm volatile ("outw %w1, (%w0)" \ - : /* no outputs */ \ - : "d"((port)), "a"((val)) \ - : "memory", "cc" \ - ); \ -} while (0) - -/* macro used to write an array of two-byte values to two consecutive ports */ -#define REP_OUTSW(port, source, count) \ -do { \ - asm volatile (" \n\ - 1: movw 0(%1), %%ax \n\ - outw %%ax, (%w2) \n\ - addl $2, %1 \n\ - decl %0 \n\ - jne 1b \n\ - " \ - : /* no outputs */ \ - : "c"((count)), "S"((source)), "d"((port)) \ - : "eax", "memory", "cc" \ - ); \ -} while (0) - -/* macro used to write an array of one-byte values to a port */ -#define REP_OUTSB(port, source, count) \ -do { \ - asm volatile (" \n\ - 1: movb 0(%1), %%al \n\ - outb %%al, (%w2) \n\ - incl %1 \n\ - decl %0 \n\ - jne 1b \n\ - " \ - : /* no outputs */ \ - : "c"((count)), "S"((source)), "d"((port)) \ - : "eax", "memory", "cc" \ - ); \ -} while (0) - -/* - * set_mode_X - * DESCRIPTION: Puts the VGA into mode X. - * INPUTS: horiz_fill_fn -- this function is used as a callback (by - * draw_horiz_line) to obtain a graphical - * image of a particular logical line for - * drawing to the build buffer - * vert_fill_fn -- this function is used as a callback (by - * draw_vert_line) to obtain a graphical - * image of a particular logical line for - * drawing to the build buffer - * OUTPUTS: none - * RETURN VALUE: 0 on success, -1 on failure - * SIDE EFFECTS: initializes the logical view window; maps video memory - * and obtains permission for VGA ports; clears video memory - */ -int set_mode_X(void (*horiz_fill_fn)(int, int, unsigned char[SCROLL_X_DIM]), - void (*vert_fill_fn)(int, int, unsigned char[SCROLL_Y_DIM])) { - - /* loop index for filling memory fence with magic numbers */ - int i; - - /* - * Record callback functions for obtaining horizontal and vertical - * line images. - */ - if (horiz_fill_fn == NULL || vert_fill_fn == NULL) - return -1; - horiz_line_fn = horiz_fill_fn; - vert_line_fn = vert_fill_fn; - - /* Initialize the logical view window to position (0,0). */ - show_x = show_y = 0; - img3_off = BUILD_BASE_INIT; - img3 = build + img3_off + MEM_FENCE_WIDTH; - - /* Set up the memory fence on the build buffer. */ - for (i = 0; i < MEM_FENCE_WIDTH; i++) { - build[i] = MEM_FENCE_MAGIC; - build[BUILD_BUF_SIZE + MEM_FENCE_WIDTH + i] = MEM_FENCE_MAGIC; - } - - /* One display page goes at the start of video memory. */ - //set this to the memory size of status bar so that status bar does not emulate - //image of the upper window - target_img = 0x05A0; - - /* Map video memory and obtain permission for VGA port access. */ - if (open_memory_and_ports() == -1) - return -1; - - /* - * The code below was produced by recording a call to set mode 0013h - * with display memory clearing and a windowed frame buffer, then - * modifying the code to set mode X instead. The code was then - * generalized into functions... - * - * modifications from mode 13h to mode X include... - * Sequencer Memory Mode Register: 0x0E to 0x06 (0x3C4/0x04) - * Underline Location Register : 0x40 to 0x00 (0x3D4/0x14) - * CRTC Mode Control Register : 0xA3 to 0xE3 (0x3D4/0x17) - */ - - VGA_blank(1); /* blank the screen */ - set_seq_regs_and_reset(mode_X_seq, 0x63); /* sequencer registers */ - set_CRTC_registers(mode_X_CRTC); /* CRT control registers */ - set_attr_registers(mode_X_attr); /* attribute registers */ - set_graphics_registers(mode_X_graphics); /* graphics registers */ - fill_palette(); /* palette colors */ - clear_screens(); /* zero video memory */ - VGA_blank(0); /* unblank the screen */ - - /* Return success. */ - return 0; -} - -/* - * clear_mode_X - * DESCRIPTION: Puts the VGA into text mode 3 (color text). - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: restores font data to video memory; clears screens; - * unmaps video memory; checks memory fence integrity - */ -void clear_mode_X() { - /* loop index for checking memory fence */ - int i; - - /* Put VGA into text mode, restore font data, and clear screens. */ - set_text_mode_3(1); - - /* Unmap video memory. */ - (void)munmap(mem_image, VID_MEM_SIZE); - - /* Check validity of build buffer memory fence. Report breakage. */ - for (i = 0; i < MEM_FENCE_WIDTH; i++) { - if (build[i] != MEM_FENCE_MAGIC) { - puts("lower build fence was broken"); - break; - } - } - for (i = 0; i < MEM_FENCE_WIDTH; i++) { - if (build[BUILD_BUF_SIZE + MEM_FENCE_WIDTH + i] != MEM_FENCE_MAGIC) { - puts("upper build fence was broken"); - break; - } - } -} - -/* - * set_view_window - * DESCRIPTION: Set the logical view window, moving its location within - * the build buffer if necessary to keep all on-screen data - * in the build buffer. If the location within the build - * buffer moves, this function copies all data from the old - * window that are within the new screen to the appropriate - * new location, so only data not previously on the screen - * must be drawn before calling show_screen. - * INPUTS: (scr_x,scr_y) -- new upper left pixel of logical view window - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: may shift position of logical view window within build - * buffer - */ -void set_view_window(int scr_x, int scr_y) { - int old_x, old_y; /* old position of logical view window */ - int start_x, start_y; /* starting position for copying from old to new */ - int end_x, end_y; /* ending position for copying from old to new */ - int start_off; /* offset of copy start relative to old build */ - /* buffer start position */ - int length; /* amount of data to be copied */ - int i; /* copy loop index */ - unsigned char* start_addr; /* starting memory address of copy */ - unsigned char* target_addr; /* destination memory address for copy */ - - /* Record the old position. */ - old_x = show_x; - old_y = show_y; - - /* Keep track of the new view window. */ - show_x = scr_x; - show_y = scr_y; - - /* - * If the new view window fits within the boundaries of the build - * buffer, we need move nothing around. - */ - if (img3_off + (scr_x >> 2) + scr_y * SCROLL_X_WIDTH >= 0 && - img3_off + 3 * SCROLL_SIZE + - ((scr_x + SCROLL_X_DIM - 1) >> 2) + - (scr_y + SCROLL_Y_DIM - 1) * SCROLL_X_WIDTH < BUILD_BUF_SIZE) - return; - - /* - * If the new screen does not overlap at all with the old screen, none - * of the old data need to be saved, and we can simply reposition the - * valid window of the build buffer in the middle of that buffer. - */ - if (scr_x <= old_x - SCROLL_X_DIM || scr_x >= old_x + SCROLL_X_DIM || - scr_y <= old_y - SCROLL_Y_DIM || scr_y >= old_y + SCROLL_Y_DIM) { - img3_off = BUILD_BASE_INIT - (scr_x >> 2) - scr_y * SCROLL_X_WIDTH; - img3 = build + img3_off + MEM_FENCE_WIDTH; - return; - } - - /* - * Any still-visible portion of the old screen should be retained. - * Rather than clipping exactly, we copy all contiguous data between - * a clipped starting point to a clipped ending point (which may - * include non-visible data). - * - * The starting point is the maximum (x,y) coordinates between the - * new and old screens. The ending point is the minimum (x,y) - * coordinates between the old and new screens (offset by the screen - * size). - */ - if (scr_x > old_x) { - start_x = scr_x; - end_x = old_x; - } - else { - start_x = old_x; - end_x = scr_x; - } - end_x += SCROLL_X_DIM - 1; - if (scr_y > old_y) { - start_y = scr_y; - end_y = old_y; - } - else { - start_y = old_y; - end_y = scr_y; - } - end_y += SCROLL_Y_DIM - 1; - - /* - * We now calculate the starting and ending addresses for the copy - * as well as the new offsets for use with the build buffer. The - * length to be copied is basically the ending offset minus the starting - * offset plus one (plus the three screens in between planes 3 and 0). - */ - start_off = (start_x >> 2) + start_y * SCROLL_X_WIDTH; - start_addr = img3 + start_off; - length = (end_x >> 2) + end_y * SCROLL_X_WIDTH + 1 - start_off + 3 * SCROLL_SIZE; - img3_off = BUILD_BASE_INIT - (show_x >> 2) - show_y * SCROLL_X_WIDTH; - img3 = build + img3_off + MEM_FENCE_WIDTH; - target_addr = img3 + start_off; - - /* - * Copy the relevant portion of the screen from the old location to the - * new one. The areas may overlap, so copy direction is important. - * (You should be able to explain why!) - */ - if (start_addr < target_addr) - for (i = length; i-- > 0; ) - target_addr[i] = start_addr[i]; - else - for (i = 0; i < length; i++) - target_addr[i] = start_addr[i]; -} - -/* - * show_screen - * DESCRIPTION: Show the logical view window on the video display. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: copies from the build buffer to video memory; - * shifts the VGA display source to point to the new image - */ -void show_screen() { - unsigned char* addr; /* source address for copy */ - int p_off; /* plane offset of first display plane */ - int i; /* loop index over video planes */ - - /* - * Calculate offset of build buffer plane to be mapped into plane 0 - * of display. - */ - p_off = (3 - (show_x & 3)); - - /* Switch to the other target screen in video memory. */ - target_img ^= 0x4000; - - /* Calculate the source address. */ - addr = img3 + (show_x >> 2) + show_y * SCROLL_X_WIDTH; - - /* Draw to each plane in the video memory. */ - for (i = 0; i < 4; i++) { - SET_WRITE_MASK(1 << (i + 8)); - copy_image(addr + ((p_off - i + 4) & 3) * SCROLL_SIZE + (p_off < i), target_img); - } - - /* - * Change the VGA registers to point the top left of the screen - * to the video memory that we just filled. - */ - OUTW(0x03D4, (target_img & 0xFF00) | 0x0C); - OUTW(0x03D4, ((target_img & 0x00FF) << 8) | 0x0D); -} - -/* - * clear_screens - * DESCRIPTION: Fills the video memory with zeroes. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: fills all 256kB of VGA video memory with zeroes - */ -void clear_screens() { - /* Write to all four planes at once. */ - SET_WRITE_MASK(0x0F00); - - /* Set 64kB to zero (times four planes = 256kB). */ - memset(mem_image, 0, MODE_X_MEM_SIZE); -} - -/* - * draw_full_block - * DESCRIPTION: Draw a BLOCK_X_DIM x BLOCK_Y_DIM block at absolute - * coordinates. Mask any portion of the block not inside - * the logical view window. - * INPUTS: (pos_x,pos_y) -- coordinates of upper left corner of block - * blk -- image data for block (one byte per pixel, as a C array - * of dimensions [BLOCK_Y_DIM][BLOCK_X_DIM]) - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: draws into the build buffer - */ -void draw_full_block(int pos_x, int pos_y, unsigned char* blk) { - int dx, dy; /* loop indices for x and y traversal of block */ - int x_left, x_right; /* clipping limits in horizontal dimension */ - int y_top, y_bottom; /* clipping limits in vertical dimension */ - - /* If block is completely off-screen, we do nothing. */ - if (pos_x + BLOCK_X_DIM <= show_x || pos_x >= show_x + SCROLL_X_DIM || - pos_y + BLOCK_Y_DIM <= show_y || pos_y >= show_y + SCROLL_Y_DIM) - return; - - /* Clip any pixels falling off the left side of screen. */ - if ((x_left = show_x - pos_x) < 0) - x_left = 0; - /* Clip any pixels falling off the right side of screen. */ - if ((x_right = show_x + SCROLL_X_DIM - pos_x) > BLOCK_X_DIM) - x_right = BLOCK_X_DIM; - /* Skip the first x_left pixels in both screen position and block data. */ - pos_x += x_left; - blk += x_left; - - /* - * Adjust x_right to hold the number of pixels to be drawn, and x_left - * to hold the amount to skip between rows in the block, which is the - * sum of the original left clip and (BLOCK_X_DIM - the original right - * clip). - */ - x_right -= x_left; - x_left = BLOCK_X_DIM - x_right; - - /* Clip any pixels falling off the top of the screen. */ - if ((y_top = show_y - pos_y) < 0) - y_top = 0; - /* Clip any pixels falling off the bottom of the screen. */ - if ((y_bottom = show_y + SCROLL_Y_DIM - pos_y) > BLOCK_Y_DIM) - y_bottom = BLOCK_Y_DIM; - /* - * Skip the first y_left pixel in screen position and the first - * y_left rows of pixels in the block data. - */ - pos_y += y_top; - blk += y_top * BLOCK_X_DIM; - /* Adjust y_bottom to hold the number of pixel rows to be drawn. */ - y_bottom -= y_top; - - /* Draw the clipped image. */ - for (dy = 0; dy < y_bottom; dy++, pos_y++) { - for (dx = 0; dx < x_right; dx++, pos_x++, blk++) - *(img3 + (pos_x >> 2) + pos_y * SCROLL_X_WIDTH + - (3 - (pos_x & 3)) * SCROLL_SIZE) = *blk; - pos_x -= x_right; - blk += x_left; - } -} - - -/* - * draw_mask - * DESCRIPTION: Draw a BLOCK_X_DIM x BLOCK_Y_DIM player image block at absolute - * coordinates by masking transparent area. And save the masked area from - * maze data in the buffer. - * Mask any portion of the block not inside - * the logical view window. - * INPUTS: (pos_x,pos_y) -- coordinates of upper left corner of block - * mask -- mask data for block of player (one byte per pixel, as a C array - * of dimensions [BLOCK_Y_DIM][BLOCK_X_DIM]) - * blk -- image data for block of player (one byte per pixel, as a C array - * of dimensions [BLOCK_Y_DIM][BLOCK_X_DIM]) - * old_block_buffer -- buffer to save background image of player from the maze - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: draws into the build buffer - */ -void draw_mask(int pos_x, int pos_y, unsigned char* mask, unsigned char* blk, unsigned char* old_block_buffer){ - int dx, dy; /* loop indices for x and y traversal of block */ - int x_left, x_right; /* clipping limits in horizontal dimension */ - int y_top, y_bottom; /* clipping limits in vertical dimension */ - - //*old_block_buffer = *blk; - //memcpy(old_block_buffer,blk, sizeof(blk)); - //old_block_buffer = blk; - - /* If block is completely off-screen, we do nothing. */ - if (pos_x + BLOCK_X_DIM <= show_x || pos_x >= show_x + SCROLL_X_DIM || - pos_y + BLOCK_Y_DIM <= show_y || pos_y >= show_y + SCROLL_Y_DIM) - return; - - /* Clip any pixels falling off the left side of screen. */ - if ((x_left = show_x - pos_x) < 0) - x_left = 0; - /* Clip any pixels falling off the right side of screen. */ - if ((x_right = show_x + SCROLL_X_DIM - pos_x) > BLOCK_X_DIM) - x_right = BLOCK_X_DIM; - /* Skip the first x_left pixels in both screen position and block data. */ - pos_x += x_left; - blk += x_left; - - /* - * Adjust x_right to hold the number of pixels to be drawn, and x_left - * to hold the amount to skip between rows in the block, which is the - * sum of the original left clip and (BLOCK_X_DIM - the original right - * clip). - */ - x_right -= x_left; - x_left = BLOCK_X_DIM - x_right; - - /* Clip any pixels falling off the top of the screen. */ - if ((y_top = show_y - pos_y) < 0) - y_top = 0; - /* Clip any pixels falling off the bottom of the screen. */ - if ((y_bottom = show_y + SCROLL_Y_DIM - pos_y) > BLOCK_Y_DIM) - y_bottom = BLOCK_Y_DIM; - /* - * Skip the first y_left pixel in screen position and the first - * y_left rows of pixels in the block data. - */ - pos_y += y_top; - blk += y_top * BLOCK_X_DIM; - /* Adjust y_bottom to hold the number of pixel rows to be drawn. */ - y_bottom -= y_top; - - /* Draw the clipped image. */ - for (dy = 0; dy < y_bottom; dy++, pos_y++) { - for (dx = 0; dx < x_right; dx++, pos_x++, blk++, mask++, old_block_buffer++){ - - /* save the original background data to old_block_buffer*/ - *old_block_buffer = *(img3 + (pos_x >> 2) + pos_y * SCROLL_X_WIDTH + - (3 - (pos_x & 3)) * SCROLL_SIZE); - - /* draw only the image of the player which is when mask is 1*/ - if(*mask == 1){ - *(img3 + (pos_x >> 2) + pos_y * SCROLL_X_WIDTH + - (3 - (pos_x & 3)) * SCROLL_SIZE) = *blk; - } - - } - pos_x -= x_right; - blk += x_left; - mask += x_left; - old_block_buffer += x_left; - } -} - - -/* - * draw_fruit_txt - * DESCRIPTION: save a TXT_X_DIM x TXT_Y_DIM image block at absolute - * coordinates. One to save, another to draw string on. - * Mask any portion of the block not inside - * the logical view window. - * INPUTS: (pos_x,pos_y) -- coordinates of upper left corner of block - * old_fruit_buffer -- image data for background (one byte per pixel, as a C array - * of dimensions [TXT_X_DIM][TXT_Y_DIM]) - * fruit_txt_buffer -- image data to draw string on (one byte per pixel, as a C array - * of dimensions [TXT_X_DIM][TXT_Y_DIM]) - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: save background data into two separate buffer - */ -void draw_fruit_txt(int pos_x, int pos_y, unsigned char* old_fruit_buffer, unsigned char* fruit_txt_buffer) { - int dx, dy; /* loop indices for x and y traversal of block */ - int x_left, x_right; /* clipping limits in horizontal dimension */ - int y_top, y_bottom; /* clipping limits in vertical dimension */ - - /* If block is completely off-screen, we do nothing. */ - if (pos_x + TXT_X_DIM <= show_x || pos_x >= show_x + SCROLL_X_DIM || - pos_y + TXT_Y_DIM <= show_y || pos_y >= show_y + SCROLL_Y_DIM) - return; - - /* Clip any pixels falling off the left side of screen. */ - if ((x_left = show_x - pos_x) < 0) - x_left = 0; - /* Clip any pixels falling off the right side of screen. */ - if ((x_right = show_x + SCROLL_X_DIM - pos_x) > TXT_X_DIM) - x_right = TXT_X_DIM; - /* Skip the first x_left pixels in both screen position and block data. */ - pos_x += x_left; - old_fruit_buffer += x_left; - fruit_txt_buffer += x_left; - - /* - * Adjust x_right to hold the number of pixels to be drawn, and x_left - * to hold the amount to skip between rows in the block, which is the - * sum of the original left clip and (width - the original right - * clip). - */ - x_right -= x_left; - x_left = TXT_X_DIM - x_right; - - /* Clip any pixels falling off the top of the screen. */ - if ((y_top = show_y - pos_y) < 0) - y_top = 0; - /* Clip any pixels falling off the bottom of the screen. */ - if ((y_bottom = show_y + SCROLL_Y_DIM - pos_y) > TXT_Y_DIM) - y_bottom = TXT_Y_DIM; - /* - * Skip the first y_left pixel in screen position and the first - * y_left rows of pixels in the block data. - */ - pos_y += y_top; - old_fruit_buffer += y_top * TXT_X_DIM; - fruit_txt_buffer += y_top * TXT_X_DIM; - - /* Adjust y_bottom to hold the number of pixel rows to be drawn. */ - y_bottom -= y_top; - - /* Draw the clipped image. */ - for (dy = 0; dy < y_bottom; dy++, pos_y++) { - for (dx = 0; dx < x_right; dx++, pos_x++, old_fruit_buffer++, fruit_txt_buffer++){ - /* save background image to both fruit_txt_buffer and old_fruit_buffer */ - *fruit_txt_buffer = *(img3 + (pos_x >> 2) + pos_y * SCROLL_X_WIDTH + - (3 - (pos_x & 3)) * SCROLL_SIZE); - *old_fruit_buffer = *(img3 + (pos_x >> 2) + pos_y * SCROLL_X_WIDTH + - (3 - (pos_x & 3)) * SCROLL_SIZE); - } - pos_x -= x_right; - old_fruit_buffer += x_left; - fruit_txt_buffer += x_left; - } -} - - -/* - * draw_mask - * DESCRIPTION: Draw a width height image with or without string at absolute - * coordinates. - * - * INPUTS: (pos_x,pos_y) -- coordinates of upper left corner of block - * string_buffer -- image data to draw (one byte per pixel, as a C array - * of dimensions [TXT_X_DIM][TXT_Y_DIM]) - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: draws into the build buffer - */ -void draw_string(int pos_x, int pos_y, unsigned char* string_buffer) { - int dx, dy; /* loop indices for x and y traversal of block */ - int x_left, x_right; /* clipping limits in horizontal dimension */ - int y_top, y_bottom; /* clipping limits in vertical dimension */ - - - /* If block is completely off-screen, we do nothing. */ - if (pos_x + TXT_X_DIM <= show_x || pos_x >= show_x + SCROLL_X_DIM || - pos_y + TXT_Y_DIM <= show_y || pos_y >= show_y + SCROLL_Y_DIM) - return; - - /* Clip any pixels falling off the left side of screen. */ - if ((x_left = show_x - pos_x) < 0){ - x_left = 0; - } - - /* Clip any pixels falling off the right side of screen. */ - if ((x_right = show_x + SCROLL_X_DIM - pos_x) > TXT_X_DIM){ - x_right = TXT_X_DIM; - } - - /* Skip the first x_left pixels in both screen position and block data. */ - pos_x += x_left; - string_buffer += x_left; - - - /* - * Adjust x_right to hold the number of pixels to be drawn, and x_left - * to hold the amount to skip between rows in the block, which is the - * sum of the original left clip and (BLOCK_X_DIM - the original right - * clip). - */ - x_right -= x_left; - x_left = TXT_X_DIM - x_right; - - /* Clip any pixels falling off the top of the screen. */ - if ((y_top = show_y - pos_y) < 0){ - y_top = 0; - } - - - /* Clip any pixels falling off the bottom of the screen. */ - if ((y_bottom = show_y + SCROLL_Y_DIM - pos_y) > TXT_Y_DIM){ - y_bottom = TXT_Y_DIM; - } - - - /* - * Skip the first y_left pixel in screen position and the first - * y_left rows of pixels in the block data. - */ - pos_y += y_top; - string_buffer += y_top * TXT_X_DIM; - /* Adjust y_bottom to hold the number of pixel rows to be drawn. */ - y_bottom -= y_top; - - for (dy = 0; dy < y_bottom ; dy++, pos_y++) { - for (dx = 0; dx < x_right ; dx++, pos_x++, string_buffer++){ - /* draw input buffer with given TXT_X_DIM and TXT_Y_DIM */ - *(img3 + (pos_x >> 2) + pos_y * SCROLL_X_WIDTH + - (3 - (pos_x & 3)) * SCROLL_SIZE)= *string_buffer; - } - pos_x -= x_right; - string_buffer += x_left; - } -} -/* - * The functions inside the preprocessor block below rely on functions - * in maze.c to generate graphical images of the maze. These functions - * are neither available nor necessary for the text restoration program - * based on this file, and are omitted to simplify linking that program. - */ -#ifndef TEXT_RESTORE_PROGRAM - -/* - * draw_vert_line - * DESCRIPTION: Draw a vertical map line into the build buffer. The - * line should be offset from the left side of the logical - * view window screen by the given number of pixels. - * INPUTS: x -- the 0-based pixel column number of the line to be drawn - * within the logical view window (equivalent to the number - * of pixels from the leftmost pixel to the line to be - * drawn) - * OUTPUTS: none - * RETURN VALUE: Returns 0 on success. If x is outside of the valid - * SCROLL range, the function returns -1. - * SIDE EFFECTS: draws into the build buffer - */ -int draw_vert_line(int x) { - /* to be written... */ - unsigned char buf[SCROLL_Y_DIM]; /* buffer for graphical image of line */ - unsigned char* addr; /* address of first pixel in build */ - /* buffer (without plane offset) */ - int p_off; /* offset of plane of first pixel */ - int i; /* loop index over pixels */ - - /* Check whether requested line falls in the logical view window. */ - if (x < 0 || x >= SCROLL_X_DIM) - return -1; - - /* Adjust y to the logical row value. */ - x += show_x; - - /* Get the image of the line. */ - (*vert_line_fn) (x, show_y, buf); - - /* Calculate starting address in build buffer. */ - addr = img3 + (x >> 2) + show_y * SCROLL_X_WIDTH; - - /* Calculate plane offset of first pixel. */ - p_off = (3 - (x & 3)); - - /* Copy image data into appropriate planes in build buffer. */ - for (i = 0; i < SCROLL_Y_DIM; i++) { - addr[p_off * SCROLL_SIZE + i * SCROLL_X_WIDTH] = buf[i]; - } - /* Return success. */ - - return 0; -} - -/* - * draw_horiz_line - * DESCRIPTION: Draw a horizontal map line into the build buffer. The - * line should be offset from the top of the logical view - * window screen by the given number of pixels. - * INPUTS: y -- the 0-based pixel row number of the line to be drawn - * within the logical view window (equivalent to the number - * of pixels from the top pixel to the line to be drawn) - * OUTPUTS: none - * RETURN VALUE: Returns 0 on success. If y is outside of the valid - * SCROLL range, the function returns -1. - * SIDE EFFECTS: draws into the build buffer - */ -int draw_horiz_line(int y) { - unsigned char buf[SCROLL_X_DIM]; /* buffer for graphical image of line */ - unsigned char* addr; /* address of first pixel in build */ - /* buffer (without plane offset) */ - int p_off; /* offset of plane of first pixel */ - int i; /* loop index over pixels */ - - /* Check whether requested line falls in the logical view window. */ - if (y < 0 || y >= SCROLL_Y_DIM) - return -1; - - /* Adjust y to the logical row value. */ - y += show_y; - - /* Get the image of the line. */ - (*horiz_line_fn) (show_x, y, buf); - - /* Calculate starting address in build buffer. */ - addr = img3 + (show_x >> 2) + y * SCROLL_X_WIDTH; - - /* Calculate plane offset of first pixel. */ - p_off = (3 - (show_x & 3)); - - /* Copy image data into appropriate planes in build buffer. */ - for (i = 0; i < SCROLL_X_DIM; i++) { - addr[p_off * SCROLL_SIZE] = buf[i]; - if (--p_off < 0) { - p_off = 3; - addr++; - } - } - - /* Return success. */ - return 0; -} - -#endif /* !defined(TEXT_RESTORE_PROGRAM) */ - -/* - * open_memory_and_ports - * DESCRIPTION: Map video memory into our address space; obtain permission - * to access VGA ports. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: 0 on success, -1 on failure - * SIDE EFFECTS: prints an error message to stdout on failure - */ -static int open_memory_and_ports() { - int mem_fd; /* file descriptor for physical memory image */ - - /* Obtain permission to access ports 0x03C0 through 0x03DA. */ - if (ioperm(0x03C0, 0x03DA - 0x03C0 + 1, 1) == -1) { - perror("set port permissions"); - return -1; - } - - /* Open file to access physical memory. */ - if ((mem_fd = open("/dev/mem", O_RDWR)) == -1) { - perror("open /dev/mem"); - return -1; - } - - /* Map video memory (0xA0000 - 0xBFFFF) into our address space. */ - if ((mem_image = mmap(0, VID_MEM_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, mem_fd, 0xA0000)) == MAP_FAILED) { - perror("mmap video memory"); - return -1; - } - - /* Close /dev/mem file descriptor and return success. */ - (void)close(mem_fd); - return 0; -} - -/* - * VGA_blank - * DESCRIPTION: Blank or unblank the VGA display. - * INPUTS: blank_bit -- set to 1 to blank, 0 to unblank - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void VGA_blank(int blank_bit) { - /* - * Move blanking bit into position for VGA sequencer register - * (index 1). - */ - blank_bit = ((blank_bit & 1) << 5); - - asm volatile (" \n\ - movb $0x01, %%al /* Set sequencer index to 1. */ \n\ - movw $0x03C4, %%dx \n\ - outb %%al, (%%dx) \n\ - incw %%dx \n\ - inb (%%dx), %%al /* Read old value. */ \n\ - andb $0xDF, %%al /* Calculate new value. */ \n\ - orl %0, %%eax \n\ - outb %%al, (%%dx) /* Write new value. */ \n\ - movw $0x03DA, %%dx /* Enable display (0x20->P[0x3C0]) */ \n\ - inb (%%dx), %%al /* Set attr reg state to index. */ \n\ - movw $0x03C0, %%dx /* Write index 0x20 to enable. */ \n\ - movb $0x20, %%al \n\ - outb %%al, (%%dx) \n\ - " - : - : "g"(blank_bit) - : "eax", "edx", "memory" - ); -} - -/* - * set_seq_regs_and_reset - * DESCRIPTION: Set VGA sequencer registers and miscellaneous output - * register; array of registers should force a reset of - * the VGA sequencer, which is restored to normal operation - * after a brief delay. - * INPUTS: table -- table of sequencer register values to use - * val -- value to which miscellaneous output register should be set - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void set_seq_regs_and_reset(unsigned short table[NUM_SEQUENCER_REGS], unsigned char val) { - /* - * Dump table of values to sequencer registers. Includes forced reset - * as well as video blanking. - */ - REP_OUTSW(0x03C4, table, NUM_SEQUENCER_REGS); - - /* Delay a bit... */ - {volatile int ii; for (ii = 0; ii < 10000; ii++);} - - /* Set VGA miscellaneous output register. */ - OUTB(0x03C2, val); - - /* Turn sequencer on (array values above should always force reset). */ - OUTW(0x03C4, 0x0300); -} - -/* - * set_CRTC_registers - * DESCRIPTION: Set VGA cathode ray tube controller (CRTC) registers. - * INPUTS: table -- table of CRTC register values to use - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void set_CRTC_registers(unsigned short table[NUM_CRTC_REGS]) { - /* clear protection bit to enable write access to first few registers */ - OUTW(0x03D4, 0x0011); - REP_OUTSW(0x03D4, table, NUM_CRTC_REGS); -} - -/* - * set_attr_registers - * DESCRIPTION: Set VGA attribute registers. Attribute registers use - * a single port and are thus written as a sequence of bytes - * rather than a sequence of words. - * INPUTS: table -- table of attribute register values to use - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void set_attr_registers(unsigned char table[NUM_ATTR_REGS * 2]) { - /* Reset attribute register to write index next rather than data. */ - asm volatile ("inb (%%dx),%%al" - : - : "d"(0x03DA) - : "eax", "memory" - ); - REP_OUTSB(0x03C0, table, NUM_ATTR_REGS * 2); -} - -/* - * set_graphics_registers - * DESCRIPTION: Set VGA graphics registers. - * INPUTS: table -- table of graphics register values to use - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: none - */ -static void set_graphics_registers(unsigned short table[NUM_GRAPHICS_REGS]) { - REP_OUTSW(0x03CE, table, NUM_GRAPHICS_REGS); -} - -/* - * fill_palette - * DESCRIPTION: Fill VGA palette with necessary colors for the maze game. - * Only the first 64 (of 256) colors are written. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: changes the first 64 palette colors - */ -static void fill_palette() { - /* 6-bit RGB (red, green, blue) values for first 64 colors */ - static unsigned char palette_RGB[64][3] = { - { 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0x2A }, /* palette 0x00 - 0x0F */ - { 0x00, 0x2A, 0x00 },{ 0x00, 0x2A, 0x2A }, /* basic VGA colors */ - { 0x2A, 0x00, 0x00 },{ 0x2A, 0x00, 0x2A }, - { 0x2A, 0x15, 0x00 },{ 0x2A, 0x2A, 0x2A }, - { 0x15, 0x15, 0x15 },{ 0x15, 0x15, 0x3F }, - { 0x15, 0x3F, 0x15 },{ 0x15, 0x3F, 0x3F }, - { 0x3F, 0x15, 0x15 },{ 0x3F, 0x15, 0x3F }, - { 0x3F, 0x3F, 0x15 },{ 0x3F, 0x3F, 0x3F }, - { 0x00, 0x00, 0x00 },{ 0x05, 0x05, 0x05 }, /* palette 0x10 - 0x1F */ - { 0x08, 0x08, 0x08 },{ 0x0B, 0x0B, 0x0B }, /* VGA grey scale */ - { 0x0E, 0x0E, 0x0E },{ 0x11, 0x11, 0x11 }, - { 0x14, 0x14, 0x14 },{ 0x18, 0x18, 0x18 }, - { 0x1C, 0x1C, 0x1C },{ 0x20, 0x20, 0x20 }, - { 0x24, 0x24, 0x24 },{ 0x28, 0x28, 0x28 }, - { 0x2D, 0x2D, 0x2D },{ 0x32, 0x32, 0x32 }, - { 0x38, 0x38, 0x38 },{ 0x3F, 0x3F, 0x3F }, - { 0x3F, 0x3F, 0x3F },{ 0x3F, 0x3F, 0x3F }, /* palette 0x20 - 0x2F */ - { 0x00, 0x00, 0x3F },{ 0x00, 0x00, 0x00 }, /* wall and player colors */ - { 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00 },{ 0x00, 0x00, 0x00 }, - { 0x10, 0x08, 0x00 },{ 0x18, 0x0C, 0x00 }, /* palette 0x30 - 0x3F */ - { 0x20, 0x10, 0x00 },{ 0x28, 0x14, 0x00 }, /* browns for maze floor */ - { 0x30, 0x18, 0x00 },{ 0x38, 0x1C, 0x00 }, - { 0x3F, 0x20, 0x00 },{ 0x3F, 0x20, 0x10 }, - { 0x20, 0x18, 0x10 },{ 0x28, 0x1C, 0x10 }, - { 0x3F, 0x20, 0x10 },{ 0x38, 0x24, 0x10 }, - { 0x3F, 0x28, 0x10 },{ 0x3F, 0x2C, 0x10 }, - { 0x3F, 0x30, 0x10 },{ 0x3F, 0x20, 0x10 } - }; - - int i,j; /* variables for loop*/ - unsigned char transparent[64][3]; /* buffer for holding trasparent rgb data */ - - /* Using interpolation among white and given colors, make new palette with trasparent rgb data */ - for(i = 0; i < 64 ; i++) { - for(j = 0; j < 3 ; j++) { - transparent[i][j] = (palette_RGB[i][j] + WHITE)/ 2 ; - } - } - - /* Start writing at color 0. */ - OUTB(0x03C8, 0x00); - /* Write all 64 colors from array. */ - REP_OUTSB(0x03C9, palette_RGB, 64 * 3); - - /* Start writing at 0x40 */ - OUTB(0x03C8, 0x40); - /* Write all 64 transparent colors from array */ - REP_OUTSB(0x03c9, transparent, 64 * 3); -} - - - -/* - * set_palette_colors - * DESCRIPTION: set particular addresss of palette with input rgb values. - * INPUTS: idx - address to where rgb values will be set. - r - r color value - g - g color alue - b - b color value - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: changes the rgb value of input address in palette - */ -void set_palette_colors(unsigned char idx, unsigned char r, unsigned char g, unsigned char b){ - /* DAC Data Register: port 3C9h - * DAC Address Write Mode Register : port 3C8h - */ - OUTB(0x3C8,idx); - - OUTB(0x3C9,r); - OUTB(0x3C9,g); - OUTB(0x3C9,b); -} - -/* - * write_font_data - * DESCRIPTION: Copy font data into VGA memory, changing and restoring - * VGA register values in order to do so. - * INPUTS: none - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: leaves VGA registers in final text mode state - */ -static void write_font_data() { - int i; /* loop index over characters */ - int j; /* loop index over font bytes within characters */ - unsigned char* fonts; /* pointer into video memory */ - - /* Prepare VGA to write font data into video memory. */ - OUTW(0x3C4, 0x0402); - OUTW(0x3C4, 0x0704); - OUTW(0x3CE, 0x0005); - OUTW(0x3CE, 0x0406); - OUTW(0x3CE, 0x0204); - - /* Copy font data from array into video memory. */ - for (i = 0, fonts = mem_image; i < 256; i++) { - for (j = 0; j < 16; j++) - fonts[j] = font_data[i][j]; - fonts += 32; /* skip 16 bytes between characters */ - } - - /* Prepare VGA for text mode. */ - OUTW(0x3C4, 0x0302); - OUTW(0x3C4, 0x0304); - OUTW(0x3CE, 0x1005); - OUTW(0x3CE, 0x0E06); - OUTW(0x3CE, 0x0004); -} - -/* - * set_text_mode_3 - * DESCRIPTION: Put VGA into text mode 3 (color text). - * INPUTS: clear_scr -- if non-zero, clear screens; otherwise, do not - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: may clear screens; writes font data to video memory - */ -static void set_text_mode_3(int clear_scr) { - unsigned long* txt_scr; /* pointer to text screens in video memory */ - int i; /* loop over text screen words */ - - VGA_blank(1); /* blank the screen */ - /* - * The value here had been changed to 0x63, but seems to work - * fine in QEMU (and VirtualPC, where I got it) with the 0x04 - * bit set (VGA_MIS_DCLK_28322_720). - */ - set_seq_regs_and_reset(text_seq, 0x67); /* sequencer registers */ - set_CRTC_registers(text_CRTC); /* CRT control registers */ - set_attr_registers(text_attr); /* attribute registers */ - set_graphics_registers(text_graphics); /* graphics registers */ - fill_palette(); /* palette colors */ - if (clear_scr) { /* clear screens if needed */ - txt_scr = (unsigned long*)(mem_image + 0x18000); - for (i = 0; i < 8192; i++) - *txt_scr++ = 0x07200720; - } - write_font_data(); /* copy fonts to video mem */ - VGA_blank(0); /* unblank the screen */ -} - -/* - * copy_image - * DESCRIPTION: Copy one plane of a screen from the build buffer to the - * video memory. - * INPUTS: img -- a pointer to a single screen plane in the build buffer - * scr_addr -- the destination offset in video memory - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: copies a plane from the build buffer to video memory - */ -static void copy_image(unsigned char* img, unsigned short scr_addr) { - /* - * memcpy is actually probably good enough here, and is usually - * implemented using ISA-specific features like those below, - * but the code here provides an example of x86 string moves - */ - //with status bar added, need to subtract its memory - asm volatile (" \n\ - cld \n\ - movl $16000-1440,%%ecx \n\ - rep movsb /* copy ECX bytes from M[ESI] to M[EDI] */ \n\ - " - : /* no outputs */ - : "S"(img), "D"(mem_image + scr_addr) - : "eax", "ecx", "memory" - ); -} - - -/* - * show_status_bar - * DESCRIPTION: Show the status bar on the video display. - * INPUTS: level -- level of the game - * n_fruits -- number of fruits - * time -- time elapsed - * backgorund_color -- color of background - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: copies from the status bar buffer to video memory; - * shifts the VGA display source to point to the new image - */ -void show_status_bar(int level, int n_fruits, int time, int background_color) { - int i; /* loop index */ - int p_off; /* plane offset */ - unsigned char image_buffer[STATUS_SCREEN_SIZE]; /* buffer for holding graphical image of the ASCII characters */ - unsigned char temp[STATUS_SCREEN_SIZE]; /* temporary image_buffer to prevent overlap */ - char txt[MAX_STRING]; /* string data buffer */ - - int second = time % 60; /* seconds */ - int second1 = second % 10; /* 1st */ - int second10 = second / 10; /* 10th */ - - int minute = time / 60; /* minutes */ - int minute1 = minute % 10; /* 1st */ - int minute10 = minute / 10; /* 10th */ - int pos; /* location index used for converting buffer to new location */ - - /* convert data into string */ - - sprintf(txt, "Level %d %d Fruit %d%d:%d%d", level, n_fruits, minute10, minute1,second10, second1); - - /* convert string into ASCII character data buffer*/ - string_to_buf(txt,image_buffer,background_color); - - - /* move pixels in ASCII character buffer to appropriate plane*/ - for(i = 0;i - * 0123012301230123012301230123012301230123012301230123012301230123 - * - * The mapping is more contorted than with mode 13h, but allows use of - * graphics tricks such as double-buffering. - * - * The design here is strongly influenced by the fact that we are running - * in a virtual machine in which writes to video memory are exorbitantly - * expensive. In particular, writing a chunk of 16kB with a single x86 - * instruction (REP MOVSB) is much faster than writing two hundred bytes - * with many instructions. - * - * That said, the design is not unreasonable, and is only slightly different - * than was (and is) often used today. - * - * Double-buffering uses two sections of memory to allow a program to - * draw the next screen to be displayed without having the partially drawn - * screen visible on the monitor (which causes flicker). When the drawing - * is complete, the video adapter is told to display the new screen instead - * of the old one, and the memory used for the old screen is then used to - * draw a third screen, the video adapter is switched back, and the process - * starts again. - * - * In our variant of double-buffering, we use non-video memory as the - * scratch pad, copy the drawn screen as a whole into one of two buffers - * in video memory, and switch the picture between the two buffers. The - * cost of the copy is negligible; the cost of writing to video memory - * instead is quite high (under VirtualPC). - * - * In order to reduce drawing time, we reuse most of the screen data between - * video frames. New data are drawn only when the viewing window moves - * within a logical space defined by the program. For example, if this - * window shifts one pixel to the left, only the left border of the screen - * is drawn. Other data are left untouched in most cases. - */ - -/* configure VGA for mode X; initializes logical view to (0,0) */ -extern int set_mode_X( - void (*horiz_fill_fn)(int, int, unsigned char[SCROLL_X_DIM]), - void (*vert_fill_fn)(int, int, unsigned char[SCROLL_Y_DIM])); - -/* return to text mode */ -extern void clear_mode_X(); - -/* set logical view window coordinates */ -extern void set_view_window(int scr_x, int scr_y); - -/* show the logical view window on the monitor */ -extern void show_screen(); - -/* clear the video memory in mode X */ -extern void clear_screens(); - -/* - * draw a 12x12 block with upper left corner at logical position - * (pos_x,pos_y); any part of the block outside of the logical view window - * is clipped (cut off and not drawn) - */ -extern void draw_full_block(int pos_x, int pos_y, unsigned char* blk); - -/* draw a horizontal line at vertical pixel y within the logical view window */ -extern int draw_horiz_line(int y); - -/* draw a vertical line at horizontal pixel x within the logical view window */ -extern int draw_vert_line(int x); - -/* show the status bar on the monitor */ -extern void show_status_bar(int level, int n_fruits,int time, int background_color); - -/* set particular palette address with rgb value */ -extern void set_palette_colors(unsigned char idx, unsigned char r, unsigned char g, unsigned char b); - -/* draw player image and save background */ -extern void draw_mask(int pos_x, int pos_y, unsigned char* mask, unsigned char* blk, unsigned char* old_block_buffer); - -/*save background image to draw text on two buffers: one for drawing and one for masking */ -extern void draw_fruit_txt(int pos_x, int pos_y, unsigned char* old_fruit_buffer, unsigned char* fruit_txt_buffer); - -/* draw buffer that has text image */ -extern void draw_string(int pos_x, int pos_y, unsigned char* string_buffer); - -#endif /* MODEX_H */ diff --git a/mp2/module/Makefile b/mp2/module/Makefile deleted file mode 100644 index b810793..0000000 --- a/mp2/module/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# Makefile for tux controller driver -# Created for ECE 391 - Fall 2007 -# By Andrew Ofisher - -obj-m += tuxctl.o -tuxctl-objs := tuxctl-ioctl.o tuxctl-ld.o - -KERNEL_DIR := /home/user/build - -all: - make -C $(KERNEL_DIR) M=$(PWD) modules - # for simplicity when using GDB, make a copy in Linux source dir - cp -f tuxctl.o $(KERNEL_DIR) - -clean:: - make -C $(KERNEL_DIR) M=$(PWD) clean - -clear: clean - rm -f Module.symvers diff --git a/mp2/module/mtcp.h b/mp2/module/mtcp.h deleted file mode 100644 index f13e056..0000000 --- a/mp2/module/mtcp.h +++ /dev/null @@ -1,398 +0,0 @@ -;/* -; mtcp.h - Mouse/TuxController Protocol -; Mark Murphy 2006 -; -; This header file defines the interface between the PC and the -; Mouse/TuxController boards. The overall philosophy was to incorporate -; both the functionality of the PS/2 Mouse (which is used by the 'layout' -; circuit simulator) as well as extend the functionality provided by the -; parallel-port based 2-button boards used previously for MP2's like the -; 'mazegame'. -; -; Commands sent from the PC to the MTC are variable length. Most are simple -; single-byte commands, however some require additional bytes to be sent. -; For example, to set the LED display, as many as 6 bytes can be sent. See -; the descriptions of individual commands for details. -; -; Responses from the MTC to the PC come in a single, 3-byte format. The -; three byte packets have a structure which is meant to allow for as much -; compatibility as possible with the PS/2 Mouse motion packet (see below). -; A few restrictions and changes had to be made to ensure higher reliability -; in the presence of untrustworthy operating systems .... -; -; (Don't worry that there is a lot of words in these next few paragraphs, -; pictures follow... ) -; -; The high order bit of the first byte of a 3-byte packet will always be -; '0', and the high order bit of the second and third bytes will always be -; '1'. If the packet is a PS/2 Mouse emulation packet, then bit 6 will be '0' -; and bit 3 will be '1'; otherwise bit 6 will be '1' and bit 3 will be '0'. -; This leaves 5 bits in which to encode opcodes for non PS/2 responses, and -; 2 7-bit fields for data. -; -; This limits the X,Y movement values for the PS/2 emulation to 8 bit 2's -; compliment integers (in the actual PS/2 spec, they are 9-bits). If you are -; familiar with the PS/2 spec, notice that this also fixes the Y,X overflow -; fields to 0. -; -; -; In a more visual form: -; -; PS/2 Emulation: -; +-7-+-6-+-5--+-4--+-3-+-2-+-1-+-0-+ -; 0 | 0 | 0 | YS | XS | 1 | M | R | L | -; +---+---+----+----+---+---+---+---+ -; 1 | 1 | X Movement | -; +---+---+----+----+---+---+---+---+ -; 2 | 1 | Y Movement | -; +---+---+----+----+---+---+---+---+ -; -; Where: -; YS - Sign (8th bit) of the Y-movement value -; XS - Sign (8th bit) of the X-movement value -; M - Status of Middle button (1 when button is down) -; R - Status of Right button (1 when button is down) -; L - Status of Left button (1 when button is down) -; -; TuxController Responses: -; +-7-+-6-+-5--+-4--+-3-+--2-+--1-+--0-+ -; 0 | 0 | 1 | R4 | R3 | 0 | R2 | R1 | R0 | -; +---+---+----+----+---+----+----+----+ -; 1 | 1 | DATA | -; +---+---+----+----+---+----+----+----+ -; 2 | 1 | DATA | -; +---+---+----+----+---+----+----+----+ -; -; Where R[4:0] is the command response code, and the DATA fields are -; specific to each particular response. -; -;*/ - -;/* -; (For reference) -; PS/2 Mouse movement packet format: -; -; 7 6 5 4 3 2 1 0 -; ------------------------------------- -; Byte 0 | YO | XO | YS | XS | 1 | M | R | L | -; ------------------------------------- -; Byte 1 | X Movement | -; ------------------------------------- -; Byte 2 | Y Movement | -; ------------------------------------- -; YO - Y overflow. Fixed 0 for MTC mouse packets -; XO - X overflow. Fixed 0 for MTC mouse packets -; YS - Y Sign -; XS - X Sign -; M - Middle Button pressed (active high) -; R - Right Button pressed (active high) -; L - Left Button pressed (active high) -;*/ - - -#define MOUSE_Y0 0x80 -#define MOUSE_X0 0x40 -#define MOUSE_YS 0x20 -#define MOUSE_XS 0x10 -#define MOUSE_MIDDLE 0x04 -#define MOUSE_RIGHT 0x02 -#define MOUSE_LEFT 0x01 - - - -;/* -; MTC to PC first bytes. Limited to 32 opcodes, however the -; MTCP_BUTTON_POLL takes up 4 opcodes -; */ - -#define MTCP_RESP(n) (((n)&7) | (((n)&0x18)<<1) | 0x40) -#define MTCP_IS_MOUSE(n) (0x08 == ((n)&0xC8)) - -#define MTCP_ACK MTCP_RESP(0x0) - -#define MTCP_BIOC_EVENT MTCP_RESP(0x1) -#define MTCP_CLK_EVENT MTCP_RESP(0x2) -#define MTCP_OFF_EVENT MTCP_RESP(0x3) - -#define MTCP_POLL_OK MTCP_RESP(0x4) -#define MCTP_CLK_POLL MTCP_RESP(0x5) -#define MTCP_RESET MTCP_RESP(0x6) - -#define MTCP_LEDS_POLL0 MTCP_RESP(0x8) -#define __LEDS_POLL01 MTCP_RESP(0x9) -#define __LEDS_POLL02 MTCP_RESP(0xa) -#define __LEDS_POLL012 MTCP_RESP(0xb) - -#define MTCP_LEDS_POLL1 MTCP_RESP(0xC) -#define __LEDS_POLL11 MTCP_RESP(0xd) -#define __LEDS_POLL12 MTCP_RESP(0xe) -#define __LEDS_POLL112 MTCP_RESP(0xf) - -#define MTCP_ERROR MTCP_RESP(0x1F) - -;/* -; PC to MTC Command Opcodes - don't change these without changing the order -; of the jump table in mainloop.asm. The defines limit the number to 32. -; */ - -#define MTCP_CMD_MASK 0x1F -#define MTCP_CMD_CHECK_MASK 0xE0 -#define MTCP_CMD_CHECK 0xC0 -#define MTCP_CMD(c) (MTCP_CMD_CHECK | (c)) - -#define MTCP_OFF MTCP_CMD(0x0) -#define MTCP_RESET_DEV MTCP_CMD(0x1) - -#define MTCP_POLL MTCP_CMD(0x2) -#define MTCP_BIOC_ON MTCP_CMD(0x3) -#define MTCP_BIOC_OFF MTCP_CMD(0x4) -#define MTCP_DBG_OFF MTCP_CMD(0x5) - -#define MTCP_LED_SET MTCP_CMD(0x6) -#define MTCP_LED_CLK MTCP_CMD(0x7) -#define MTCP_LED_USR MTCP_CMD(0x8) -#define MTCP_POLL_LEDS MTCP_CMD(0x13) - -#define MTCP_CLK_RESET MTCP_CMD(0x9) -#define MTCP_CLK_SET MTCP_CMD(0xa) -#define MTCP_CLK_POLL MTCP_CMD(0xb) -#define MTCP_CLK_RUN MTCP_CMD(0xc) -#define MTCP_CLK_STOP MTCP_CMD(0xd) -#define MTCP_CLK_UP MTCP_CMD(0xe) -#define MTCP_CLK_DOWN MTCP_CMD(0xf) -#define MTCP_CLK_MAX MTCP_CMD(0x10) - -#define MTCP_MOUSE_OFF MTCP_CMD(0x11) -#define MTCP_MOUSE_ON MTCP_CMD(0x12) - - - - -;/* -; ************************** Commands ******************************** -; -; Opcode: MTCP_RESET_DEV -; Reset the device. The device doesn't immediately respond, but -; generates an MTCP_RESET event when it is finished initializing -; itself. -; -; Opcode: MTCP_OFF -; Turn the MTC off. The RESET button on the board will need to be -; pressed for it to resume operation. It will generate an -; MTCP_OFF_EVENT before going to sleep. This is only a valid command -; when debug mode is off (i.e. the PC has sent an MTCP_DBG_OFF -; command). -; -; Opcode: MTCP_POLL -; Poll Buttons - get the current status of the 8 buttons. -; The bitmask is active low - a bit is clear when the corresponding -; button is pressed. The bitmask is split into two bytes. -; -; Response packet: -; byte 0 - MTCP_POLL_OK -; byte 1 __7_____4___3___2___1_____0____ -; | 1 X X X | C | B | A | START | -; ------------------------------- -; byte 2 __7_____4_____3______2______1_____0___ -; | 1 X X X | right | down | left | up | -; -------------------------------------- -; -; Opcode: MTCP_BIOC_ON -; Enable Button interrupt-on-change. MTCP_ACK is returned. -; -; Opcode: MTCP_BIOC_OFF -; Disable Button interrupt-on-change. MTCP_ACK is returned. -; -; Opcode MTCP_DBG_OFF -; Disable Debug-lockup mode. This sets the error-handling behavior; -; when debug-lockup is on, the device displays 0xdEAd on the LEDs and -; ceases responding to commands. MTCP_ACK is returned -; -; Opcode MTCP_LED_SET -; Set the User-set LED display values. These will be displayed on the -; LED displays when the LED display is in USR mode (see the MTCP_LED_USR -; and MTCP_LED_CLK commands). The first byte of argument specifies -; which of the LED's to set, and also determines how many bytes will -; follow - one byte for each led to set. -; -; -; Mapping from 7-segment to bits -; The 7-segment display is: -; _A -; F| |B -; -G -; E| |C -; -D .dp -; -; The map from bits to segments is: -; -; __7___6___5___4____3___2___1___0__ -; | A | E | F | dp | G | C | B | D | -; +---+---+---+----+---+---+---+---+ -; -; Arguments: >= 1 bytes -; byte 0 - Bitmask of which LED's to set: - -; __7___6___5___4____3______2______1______0___ -; | X | X | X | X | LED3 | LED2 | LED1 | LED0 | -; ----+---+---+---+------+------+------+------+ -; -; The number of bytes which should follow should be equal to the -; number of bits set in byte 0. The bytes should be sent in order of -; increasing LED number. (e.g LED0, LED2, LED3 for a bitmask of 0x0D) -; -; Response: 1 byte -; byte 0 - MTCP_ACK -; -; Opcode MTCP_LED_CLK -; Put the LED display into clock mode. In this mode, the value of the -; clock is displayed, rather than the value set with MTCP_LED_SET. -; -; Opcode MTCP_LED_USR -; Put the LED display into user-mode. In this mode, the value specified -; by the MTCP_LED_SET command is displayed. -; -; Opcode MTCP_CLK_RESET -; Reset the clock. The clock value is set to zero, the direction is -; set to down, and it is stopped. -; -; Opcode MTCP_CLK_SET -; Set the value of the clock. There are two argument bytes, the first -; is the number of minues, the second is the number of seconds. If -; either argument is out of the range which makes sense, then the -; result is undefined. -; -; Arguments: 2 bytes -; byte 0 - Number of minutes to set (up to a maximum of 99). -; byte 1 - number of seconds to set (up do a maximum of 59). -; -; Opcode MTCP_CLK_MAX -; Set the maximum value of the clock. When the clock's direction -; is set to up and it counts to this value, the MTC will generate -; an MTCP_CLK_EVENT event. -; Arguments: 2 bytes -; byte 0 - Number of minutes to set (up to a maximum of 99). -; -; Opcode MTCP_CLK_POLL -; Command: -; Read the state of the clock. The result specifies whether the -; clock is running, its direction, and the current value in -; minutes and seconds. -; Arguments: 0 bytes -; Response packet: -; byte 0 : MTCP_POLL_OK -; byte 1 : -; +-7-+-6-5-4-3-2-1-0-+ -; | 1 | Minutes | -; +---+---------------+ -; byte 2 : -; +-7-+----6----+-5-4-3-2-1-0--+ -; | 1 | Running | Seconds | -; +---+---------+--------------+ -; -; Opcode MTCP_CLK_RUN -; Start the clock. If it was already running, then it will still -; be running after this command. -; -; Opcode MTCP_CLK_STOP -; Stop the clock. If it was already stopped, then it will still be -; stopped after this command. -; -; Opcode MTCP_CLK_UP -; Set the clock's direction to up. When running, It will count up -; until reaching the value set by MTCP_CLK_MAX, then generate a -; CLK_EVENT -; -; Opcode MTCP_CLK_DOWN -; Set the clock"s direction to Down. When running, it will count down -; until reaching zero, then generate a CLK_EVENT. -; -;*/ - -;/* -; ********************* Responses ************************* -; -; MTCP_ERROR -; Response when the MTC has debug-lockup disabled and receives an -; unrecognized request from the PC. -; -; MTCP_ACK -; Response when the MTC successfully completes a command. -; -; MTCP_POLL_OK -; First byte of a response to a poll of either the buttons or the -; clock. -; -; MTCP_RESET -; Generated when the devide re-initializes itself after a power-up, -; a RESET button press, or an MTCP_RESET_DEV command. -; -; Packet Format: -; Byte 0 - MTCP_RESET -; Byte 1 - reserved -; Byte 2 - reserved -; -; MTCP_OFF -; Generated when the device is turning itself off after either an -; MTCP_OFF command or its internal 2-hour timer has expired. This -; timer is reset anytime there is serial communication activity, -; either to or from the device. -; -; Packet Format: -; Byte 0 - MTCP_OFF_EVENT -; Byte 1 - reserved -; Byte 2 - reserved -; -; MTCP_BIOC_EVT -; Generated when the Button Interrupt-on-change mode is enabled and -; a button is either pressed or released. -; -; Packet format: -; Byte 0 - MTCP_BIOC_EVENT -; byte 1 +-7-----4-+-3-+-2-+-1-+---0---+ -; | 1 X X X | C | B | A | START | -; +---------+---+---+---+-------+ -; byte 2 +-7-----4-+---3---+--2---+--1---+-0--+ -; | 1 X X X | right | down | left | up | -; +---------+-------+------+------+----+ -; MTCP_CLK_EVENT -; The clock has reached zero (when counting down) or its maximum value -; (when counting up). -; -; Packet format: -; Byte 0 - MTCP_CLK_EVENT -; Byte 1 - reserved -; Byte 2 - reserved -; -; MTCP_LEDS_POLL -; Since there are 32 bits of data to return with this response, the -; data format is a bit screwy. It will be 2 3-byte packets of the -; form described above, with a slight modification: the opcode will -; be used to encode some of the data. There is a different opcode -; for the first and second packets (1 bit of difference) to allow for -; detection of a dropped packet. -; The data from LED's 0 and 1 will be in the first packet, and the -; data from LED's 2 and 3 will be in the second packet. The data will -; be of the same format as the LED_SET command, except that the segA -; bits will be packed into the opcode, as shown in the diagram below -; -; In picto-gram form: -; Packet 0 will be: -; +-7-+-6-+-5-+--4-+-3-+-2-+-1--+-0--+ -; 0 | 0 | 1 | 0 | 1 | 0 | 0 | A1 | A0 | -; +---+---+---+----+---+---+----+----+ -; 1 | 1 | E | F | dp | G | C | B | D | (data for LED0) -; +---+---+---+----+---+---+----+----+ -; 2 | 1 | E | F | dp | G | C | B | D | (data for LED1) -; +---+---+---+----+---+---+----+----+ -; -; Packet 1 will be: -; +-7-+-6-+-5-+--4-+-3-+-2-+-1--+-0--+ -; 0 | 0 | 1 | 0 | 1 | 0 | 1 | A1 | A0 | -; +---+---+---+----+---+---+----+----+ -; 1 | 1 | E | F | dp | G | C | B | D | (data for LED2) -; +---+---+---+----+---+---+----+----+ -; 2 | 1 | E | F | dp | G | C | B | D | (data for LED3) -; +---+---+---+----+---+---+----+----+ -; -;*/ diff --git a/mp2/module/tuxctl-ioctl.c b/mp2/module/tuxctl-ioctl.c deleted file mode 100644 index 2aaa3d6..0000000 --- a/mp2/module/tuxctl-ioctl.c +++ /dev/null @@ -1,246 +0,0 @@ -/* tuxctl-ioctl.c - * - * Driver (skeleton) for the mp2 tuxcontrollers for ECE391 at UIUC. - * - * Mark Murphy 2006 - * Andrew Ofisher 2007 - * Steve Lumetta 12-13 Sep 2009 - * Puskar Naha 2013 - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tuxctl-ld.h" -#include "tuxctl-ioctl.h" -#include "mtcp.h" - -#define debug(str, ...) \ - printk(KERN_DEBUG "%s: " str, __FUNCTION__, ## __VA_ARGS__) - - -/* fill a buffer with initializing commands and send them to TUX*/ -int init(struct tty_struct* tty); -int set_led(struct tty_struct* tty, unsigned long arg); -int set_buttons(struct tty_struct* tty, unsigned long arg); -unsigned char packets [BUTTON_PACKET_SIZE]; /* array for holding packets b and c for MTCP_BIOC_EVENT */ -unsigned char prev_state [LED_PACKET_SIZE]; /* array for holding previous state in case of reset */ -int ack; /* MTCP_ACK flag */ - -/************************ Protocol Implementation *************************/ - -/* tuxctl_handle_packet() - * IMPORTANT : Read the header for tuxctl_ldisc_data_callback() in - * tuxctl-ld.c. It calls this function, so all warnings there apply - * here as well. - */ - -void tuxctl_handle_packet (struct tty_struct* tty, unsigned char* packet) -{ - unsigned a, b, c; - - a = packet[0]; /* byte 0 */ - b = packet[1]; /* byte 1 */ - c = packet[2]; /* byte 2 */ - - switch(a) { - - case MTCP_RESET: - init(tty); - - /* send data saved before reset to TUX */ - tuxctl_ldisc_put(tty,prev_state,6); - break; - - case MTCP_BIOC_EVENT: - // Byte 0 - MTCP_BIOC_EVENT - // byte 1 +-7-----4-+-3-+-2-+-1-+---0---+ - // | 1 X X X | C | B | A | START | - // +---------+---+---+---+-------+ - // byte 2 +-7-----4-+---3---+--2---+--1---+-0--+ - // | 1 X X X | right | down | left | up | - // +---------+-------+------+------+----+ - packets[0] = b; - packets[1] = c; - break; - - case MTCP_ACK: - ack = ACK_ON; - break; - default: - break; - - } - - //printk("packet : %x %x %x\n", a, b, c); -} - -/******** IMPORTANT NOTE: READ THIS BEFORE IMPLEMENTING THE IOCTLS ************ - * * - * The ioctls should not spend any time waiting for responses to the commands * - * they send to the controller. The data is sent over the serial line at * - * 9600 BAUD. At this rate, a byte takes approximately 1 millisecond to * - * transmit; this means that there will be about 9 milliseconds between * - * the time you request that the low-level serial driver send the * - * 6-byte SET_LEDS packet and the time the 3-byte ACK packet finishes * - * arriving. This is far too long a time for a system call to take. The * - * ioctls should return immediately with success if their parameters are * - * valid. * - * * - ******************************************************************************/ -int -tuxctl_ioctl (struct tty_struct* tty, struct file* file, - unsigned cmd, unsigned long arg) -{ - - switch (cmd) { - - case TUX_INIT: - init(tty); - return 0; - - case TUX_BUTTONS: - return set_buttons(tty,arg); - - case TUX_SET_LED: - if(ack == ACK_OFF){ - return 0; - } - ack = ACK_OFF; /* set ack flag to off to wait for another ACK*/ - return set_led(tty, arg); - - case TUX_LED_ACK: - return -EINVAL; - case TUX_LED_REQUEST: - return -EINVAL; - case TUX_READ_LED: - return -EINVAL; - default: - return -EINVAL; - } -} - - -/* set_buttons() -* takes packets value and mask and shift accordingly and send the data to user for behavior. -* input: arg -- pointer to a 32bit integer where low byte will be set. -* -*/ -int set_buttons(struct tty_struct* tty, unsigned long arg){ - /* variable used for TUX_INIT */ - - /* variables used for TUX_BUTTONS */ - unsigned char tmp1; /* temporary holder for 0000 CBAS */ - unsigned char tmp2; /* temporary holder for RDLU 0000 */ - unsigned char bit5; /* temporary holder for 5th bit */ - unsigned char bit6; /* temporary holder for 6th bit */ - unsigned char result; /* final output RLDU CBAS to send to user */ - - /* mask packet data and shift accordingly*/ - tmp1 = packets[0] & 0x0F; /* 0000 CBAS */ - tmp2 = (packets[1] & 0x0F) << 4; /* RDLU 0000 */ - - /* mask 5th and 6th bit and swap them*/ - bit5 = tmp2 & MASK_5; /* 0010 0000 */ - bit5 = bit5 << 1; - bit6 = tmp2 & MASK_6; /* 0100 0000*/ - bit6 = bit6 >> 1; - tmp2 = tmp2 & MASK_47; /* 1001 0000 */ - - tmp2 = tmp2 | bit5 | bit6; /* RLDU 0000 */ - result = tmp1 | tmp2; /* RLDU CBAS */ - - /* send data to user and check if arg is NULL */ - if (copy_to_user( (unsigned long*)arg, &result ,sizeof(result)) != 0){ - return -EINVAL; - }else{ - return 0; - } -} - - -/* set_led() -* takes argument and mask and shift accordingly and send the data to TUX to set led. -* input: arg -- 32 bit interger that consists of led information. -* -*/ -int set_led(struct tty_struct* tty, unsigned long arg){ - - // /* varibles used for TUX_SET_LED */ - // - // /* - // * __7___6___5___4____3___2___1___0__ - // * | A | E | F | dp | G | C | B | D | - // * +---+---+---+----+---+---+---+---+ - // * led hex value from 0-F - // */ - unsigned char led_bit; /* determines which led to turn on */ - unsigned char dot_bit; /* determine which dot to turn on */ - int i; /* varible used for looping */ - unsigned char led[16] ={0xE7, 0x06, 0xCB, 0x8F, 0x2E, 0xAD, 0xED, 0x86, 0xEF, 0xAE, 0xEE, 0x6D, 0xE1, 0x4F, 0xE9, 0xE8}; - - - unsigned char output[LED_PACKET_SIZE]; /* buffer that holds final led data to send to TUX */ - unsigned char display_value[DISPLAY_SIZE]; /* buffer that holds display data */ - - - output[0] = MTCP_LED_SET; - - /* intialize display with zero*/ - for(i = 0; i < DISPLAY_SIZE ;i++){ - output[MIN_LED_BYTES+i] = EMTPY; - } - - /* mask input arg and shift to get led_bit and dot_bit */ - led_bit = (arg >> 16) & MASK_0TO3; /* get low 4bits of third byte */ - dot_bit = (arg >> 24) & MASK_0TO3; /* get low 4bits of higheset byte */ - - /* save hexadecimal values whose led is set to ON */ - for(i = 0; i < DISPLAY_SIZE ;i++){ - display_value[i] = (arg >> (i*4)) & MASK_0TO3; - if(((led_bit >> i) & 0x1) == 1){ - output[i+2] = led[display_value[i]]; - } - if(((dot_bit >> i) & 0x1) == 1){ /* set dots to ON accordingly */ - output[i+2] |= DOT_MASK; - } - - } - output[1] = ALL_LED; - - /* save current state to a buffer for RESET */ - for(i=0; i -#include - -#include -#include -#include - -#include -#include "tuxctl-ld.h" - -#define uhoh(str, ...) printk(KERN_EMERG "%s " str, __FUNCTION__, ##__VA_ARGS__) -#define debug(str, ...) printk(KERN_DEBUG "%s " str, __FUNCTION__,\ - ## __VA_ARGS__) - -/* Here's an interesting tidbit: tty_struct has no synchronization available - * to us to protect against races involving the tty->disc_data field. So, - * rather than do something tricky, we'll employ the 'one-big-freakin-lock' - * strategy for synchronizing the methods in this file. This can't be a - * semaphore because of the following chain of function calls: - * - * rs_interrupt() (serial.c) - * tty_flip_buffer_push() (tty_io.c) - * flush_to_ldisc() (tty_io.c) - * ldisc.receive_buf() (this file) - * - * Specifically, rs_interrupt is, well, an interrupt. Sleeping in an - * interrupt is a recipe for breaking things, so a spinlock it is. - */ -static spinlock_t tuxctl_ldisc_lock = SPIN_LOCK_UNLOCKED; - - -/* Line Discipline specific stuff */ -#define TUXCTL_MAGIC 0x74757863 - -#define sanity(data) if((data)->magic != TUXCTL_MAGIC){\ - uhoh("MAGIC MISMATCH!\n");\ - BUG();} - - -static int tuxctl_ldisc_open(struct tty_struct*); -static void tuxctl_ldisc_close(struct tty_struct*); -static void tuxctl_ldisc_rcv_buf(struct tty_struct*, const unsigned char *, - char *, int); -static void tuxctl_ldisc_write_wakeup(struct tty_struct*); -static void tuxctl_ldisc_data_callback(struct tty_struct *tty); - -#define TUXCTL_BUFSIZE 64 -typedef struct tuxctl_ldisc_data { - unsigned long magic; - - char rx_buf[TUXCTL_BUFSIZE]; - int rx_start, rx_end; - - char tx_buf[TUXCTL_BUFSIZE]; - int tx_start, tx_end; - -} tuxctl_ldisc_data_t; - - -static struct tty_ldisc tuxctl_ldisc = { - .magic = TUXCTL_MAGIC, - .name = "tuxcontroller", - .open = tuxctl_ldisc_open, - .close = tuxctl_ldisc_close, - .ioctl = tuxctl_ioctl, - .receive_buf = tuxctl_ldisc_rcv_buf, - .write_wakeup = tuxctl_ldisc_write_wakeup, -}; - -int __init -tuxctl_ldisc_init(void) -{ - int err = 0; - if((err = tty_register_ldisc(N_MOUSE, &tuxctl_ldisc))){ - debug("tuxctl line discipline register failed\n"); - }else{ - printk("tuxctl line discipline registered\n"); - } - return err; -} -module_init(tuxctl_ldisc_init); - -void __exit -tuxctl_ldisc_exit(void) -{ - tty_unregister_ldisc(N_MOUSE); - printk("tuxctl line discipline removed\n"); -} -module_exit(tuxctl_ldisc_exit); - - -#define buf_used(start,end) ((start) <= (end) ? \ - ((end) - (start)) \ - : (TUXCTL_BUFSIZE + (end) - (start))) - -#define buf_room(start,end) (TUXCTL_BUFSIZE - buf_used(start,end) - 1) - -#define buf_empty(start, end) ((start) == (end)) -#define buf_full(start, end) ((((end)+1)%TUXCTL_BUFSIZE) == (start)) -#define buf_incidx(idx) ((idx) = ((idx)+1) % TUXCTL_BUFSIZE) - - -static int -tuxctl_ldisc_open(struct tty_struct *tty) -{ - tuxctl_ldisc_data_t *data; - unsigned long flags; - - if(!(data = kmalloc(sizeof(*data), GFP_KERNEL))){ - uhoh("kmalloc failed!\n"); - return -ENOMEM; - } - - spin_lock_irqsave(&tuxctl_ldisc_lock, flags); - - data->magic = TUXCTL_MAGIC; - - data->rx_start = 0; - data->rx_end = 0; - - data->tx_start = 0; - data->tx_end = 0; - tty->disc_data = data; - - spin_unlock_irqrestore(&tuxctl_ldisc_lock, flags); - - return 0; -} - -static void -tuxctl_ldisc_close(struct tty_struct *tty) -{ - tuxctl_ldisc_data_t *data; - unsigned long flags; - - spin_lock_irqsave(&tuxctl_ldisc_lock, flags); - - data = tty->disc_data; - tty->disc_data = 0; - - spin_unlock_irqrestore(&tuxctl_ldisc_lock, flags); - - kfree(data); -} - - -/* tuxctl_ldisc_rcv_buf - * The receive_buf() method of our line discipline. It receives count bytes - * from cp. fp points to some flag/error bytes which I conveniently ignore. - * This is called when there are bytes received from the serial driver, and - * is called from an interrupt handler. - */ -static void -tuxctl_ldisc_rcv_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) -{ - int call = 0, c=0; - unsigned long flags; - tuxctl_ldisc_data_t *data; - - spin_lock_irqsave(&tuxctl_ldisc_lock, flags); - if(0 != (data = tty->disc_data)){ - call = 1; - - while(count-- > 0 && !buf_full(data->rx_start, data->rx_end)) { - data->rx_buf[data->rx_end] = *cp++; - buf_incidx(data->rx_end); - c++; - } - } - - spin_unlock_irqrestore(&tuxctl_ldisc_lock, flags); - - if(call){ - tuxctl_ldisc_data_callback(tty); - } -} - -/* tuxctl_ldisc_write_wakeup() - * Called by the lower level serial driver when it can accept more - */ -static void -tuxctl_ldisc_write_wakeup(struct tty_struct *tty) -{ - tuxctl_ldisc_data_t *data; - int sent, n = 0, room; - char buf[TUXCTL_BUFSIZE]; - unsigned long flags; - - /* I hope that this doesn't need synchronization. */ - room = tty->driver->write_room(tty); - - spin_lock_irqsave(&tuxctl_ldisc_lock, flags); - data = tty->disc_data; - - while(n <= room && !buf_empty(data->tx_start, data->tx_end)){ - buf[n++] = data->tx_buf[data->tx_start]; - buf_incidx(data->tx_start); - } - - spin_unlock_irqrestore(&tuxctl_ldisc_lock, flags); - - sent = tty->driver->write(tty, buf, n); - - if(sent != n){ - debug("driver lied to us? We lost some data"); - } -} - -/*********** Interface to the char driver ********************/ - - -/* tuxctl_ldisc_get() - * Read bytes that the line-discipline has received from the controller. - * Returns the number of bytes actually read, or -1 on error (if, for - * example, the first argument is invalid. - */ -int -tuxctl_ldisc_get(struct tty_struct *tty, char *buf, int n) -{ - tuxctl_ldisc_data_t *data; - unsigned long flags; - int r = 0; - - spin_lock_irqsave(&tuxctl_ldisc_lock, flags); - data = tty->disc_data; - while(n-- > 0 && !buf_empty(data->rx_start, data->rx_end)){ - *buf++ = data->rx_buf[data->rx_start]; - buf_incidx(data->rx_start); - r++; - } - spin_unlock_irqrestore(&tuxctl_ldisc_lock, flags); - - return r; -} - -/* tuxctl_ldisc_put() - * Write bytes out to the device. Returns the number of bytes *not* written. - * This means, 0 on success and >0 if the line discipline's internal buffer - * is full. - */ -int -tuxctl_ldisc_put(struct tty_struct *tty, char const *buf, int n) -{ - tuxctl_ldisc_data_t *data; - unsigned long flags; - - spin_lock_irqsave(&tuxctl_ldisc_lock, flags); - - data = tty->disc_data; - - while (n > 0 && !buf_full(data->tx_start, data->tx_end)) { - data->tx_buf[data->tx_end] = *buf++; - buf_incidx(data->tx_end); - --n; - } - - spin_unlock_irqrestore(&tuxctl_ldisc_lock, flags); - - /* Potential race conditions here ... ?*/ - - tuxctl_ldisc_write_wakeup(tty); - - return n; -} - -/* tuxctl_ldisc_data_callback() - * This is the function called from the line-discipline when data is - * available from the device. This is how responses to polling the buttons - * and ACK's for setting the LEDs will be transmitted to the tuxctl driver. - * The tuxctl driver must implement this function. The 'tty' parameter - * can be passed back to the tuxctl_ldisc_read function to read - * data from the lower-level buffers. - * - * IMPORTANT: This function is called from an interrupt context, so it - * cannot acquire any semaphores or otherwise sleep, or access - * the 'current' pointer. It also must not take up too much time. - */ -static void tuxctl_ldisc_data_callback(struct tty_struct *tty) -{ - /* Should probably synchronize these */ - static unsigned char saved[2]; - static int n_saved = 0; - - unsigned char packet[12], *p; - int n, i = 0, j; - - for(i=0; i< n_saved; i++) - packet[i] = saved[i]; - - n = n_saved + tuxctl_ldisc_get(tty, packet + n_saved, 12 - n_saved); - - /* Look at all bytes as potential packet beginnings except for - * the last two bytes. Save them for next time. */ - for(i = 0; i < n-2; ){ - p = packet + i; - - /* Check the framing bits to detect lost bytes */ - if(!(p[0]&0x80) && p[1]&0x80 && p[2]&0x80){ - tuxctl_handle_packet(tty, p); - i += 3; - }else{ - i++; - } - } - - /* Save the leftovers - extra bytes for breakfast */ - n_saved = n - i; - for(j = 0; j < n_saved; j++) - saved[j] = packet[i+j]; -} - diff --git a/mp2/module/tuxctl-ld.h b/mp2/module/tuxctl-ld.h deleted file mode 100644 index f5b353d..0000000 --- a/mp2/module/tuxctl-ld.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef TUXCTL_LD_H -#define TUXCTL_LD_H - -#include -#include -#include -#include - -/* tuxctl-ld.h - * Interface between line discipline and driver */ - -/* tuxctl_ldisc_get() - * Read bytes that the line-discipline has received from the controller. - * Returns the number of bytes actually read, or -1 on error (if, for - * example, the first argument is invalid. - */ -extern int tuxctl_ldisc_get(struct tty_struct*, char *, int); - - -/* tuxctl_ldisc_put() - * Write bytes out to the device. Returns the number of bytes *not* written. - * This means, 0 on success and >0 if the line discipline's internal buffer - * is full. - */ -extern int tuxctl_ldisc_put(struct tty_struct*, char const*, int); - -/* tuxctl_handle_packet - * To be written by the student. This function will handle a - * packet sent to the computer from the tux controller. This is - * called by tuxctl_ldisc_data_callback(). - */ -void tuxctl_handle_packet(struct tty_struct *tty, unsigned char *packet); - - -/* ioctl for the line discipline that the students will implement. - * Located in tuxctl.c - */ -extern int tuxctl_ioctl(struct tty_struct * tty, struct file *, unsigned int cmd, unsigned long arg); -#endif diff --git a/mp2/text.c b/mp2/text.c deleted file mode 100644 index c48de77..0000000 --- a/mp2/text.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * tab:4 - * - * text.c - font data and text to graphics conversion utility - * - * "Copyright (c) 2004-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 2 - * Creation Date: Thu Sep 9 22:06:29 2004 - * Filename: text.c - * History: - * SL 1 Thu Sep 9 22:06:29 2004 - * First written. - * SL 2 Sat Sep 12 13:45:33 2009 - * Integrated original release back into main code base. - */ - -#include - -#include "text.h" - -/* - * These font data were read out of video memory during text mode and - * saved here. They could be read in the same manner at the start of a - * game, but keeping a copy allows us to run the game to fix text mode - * if it is broken (font data missing, usually). - * - * Each character is 8x16 pixels and occupies two lines in the table below. - * Each byte represents a single bitmapped line of a single character. - */ -unsigned char font_data[256][16] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, - 0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3, - 0xE7, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, - 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, - 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7, 0xE7, - 0xE7, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, - 0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, - 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, - 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, - 0x42, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99, 0xBD, - 0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32, 0x78, 0xCC, - 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, - 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x30, - 0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x63, - 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7, - 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xF8, - 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0xFE, 0x3E, - 0x1E, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, - 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, - 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, - 0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, - 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0xFE, - 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, - 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, - 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6C, 0xFE, - 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C, - 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, - 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, - 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, - 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, - 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18, - 0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, - 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, - 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, - 0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, - 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, - 0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06, - 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18, - 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, - 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, - 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, - 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, - 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, - 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, - 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, - 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, - 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, - 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, - 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, - 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xE6, 0x66, 0x66, 0x6C, 0x78, 0x78, - 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, - 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, - 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00}, - {0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C, - 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, - 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, - 0xD6, 0xFE, 0xEE, 0x6C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, - 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30, - 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, - 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00}, - {0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, - 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, - 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, - 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, - 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00}, - {0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, - 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00}, - {0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, - 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6, - 0xD6, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x66, - 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, - 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, - 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6, - 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, - 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, - 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, - 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, - 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, - 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, - 0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00}, - {0x00, 0x00, 0xCC, 0x00, 0x00, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE, - 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x10, 0x38, 0x6C, 0x00, 0x78, 0x0C, 0x7C, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xCC, 0x00, 0x00, 0x78, 0x0C, 0x7C, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x60, - 0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x00, 0x00, 0x00}, - {0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE, - 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xFE, - 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE, - 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0xC6, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, - 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6, - 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x30, 0x60, 0x00, 0xFE, 0x66, 0x60, 0x7C, - 0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x76, 0x36, - 0x7E, 0xD8, 0xD8, 0x6E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC, 0xFE, 0xCC, - 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00}, - {0x00, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x60, 0x60, - 0x66, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, - 0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, - 0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0xF8, 0xCC, 0xCC, 0xF8, 0xC4, 0xCC, 0xDE, - 0xCC, 0xCC, 0xCC, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x0E, 0x1B, 0x18, 0x18, 0x18, 0x7E, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00}, - {0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0C, 0x7C, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x0C, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x18, 0x30, 0x60, 0x00, 0x7C, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, - {0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, - 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, - 0xC0, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, - 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, - 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, - 0x60, 0xDC, 0x86, 0x0C, 0x18, 0x3E, 0x00, 0x00}, - {0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, - 0x66, 0xCE, 0x9E, 0x3E, 0x06, 0x06, 0x00, 0x00}, - {0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, - 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6C, 0xD8, - 0x6C, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6C, 0x36, - 0x6C, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44}, - {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, - 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA}, - {0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, - 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xF7, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0}, - {0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F}, - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8, - 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xD8, 0xCC, - 0xC6, 0xC6, 0xC6, 0xCC, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, - 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30, 0x18, - 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, - 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x7C, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66, 0x66, - 0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, - 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, - 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C, 0x3E, 0x66, - 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB, - 0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xDB, 0xDB, - 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C, 0x60, - 0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, - 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, - 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, - 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, - 0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, - {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E, - 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, - 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, - 0x6C, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x70, 0xD8, 0x30, 0x60, 0xC8, 0xF8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C, - 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -}; - -/* - * string_to_buf - * DESCRIPTION: convert input string data into buffer holding ASCII data of the input string - * INPUTS: string -- string data to be converted in to ASCII buffer - * image_buffer -- buffer that will be holding ASCII character data of the string - * background color -- color value that differs depends on the level of the game - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: buffer now holds the ASCII character data of the string - * - */ -void string_to_buf(const char* string, unsigned char* image_buffer, int background_color){ - int i,j,k; /* index for loop */ - unsigned char text_color = BLACK; /* font color hex value*/ - unsigned char* current_character; /* holder for each string data*/ - int str_len = strlen(string); /* length of input string*/ - int idx = 0; /* index for inputting appropriate color data into buffer*/ - int center_offset = (STATUS_X_DIM - str_len*FONT_WIDTH)/2; /* center offset calculation*/ - int mask = 0x80; /* masking value */ - - /* fill the buffer with background color*/ - for(i = 0; i < STATUS_X_DIM*STATUS_Y_DIM ;i++){ - image_buffer[i] = background_color; - } - - /*compare bit value of each string and store them into the image_buffer*/ - for(i = 0; i < str_len; i++){ - int font_index = (int)string[i]; - current_character = font_data[font_index]; - for(j = 0; j < FONT_HEIGHT ; j++){ - mask = 0x80; - for(k = 0; k < FONT_WIDTH ; k++){ - - /* calculate index using offset, size of status barm and size of font */ - idx = STATUS_X_DIM + center_offset + j * STATUS_X_DIM + k + i * FONT_WIDTH; - if(current_character[j] & mask) { - image_buffer[idx] = text_color; - } - mask = mask >> 1; - - } - } - } -} - -/* - * string_to_buf_fruit - * DESCRIPTION: convert input string data into buffer holding ASCII data of the input string and wrtie that buffer on to input buffer - * INPUTS: string -- string data to be converted in to ASCII buffer and written onto input buffer - * fruit_buffer -- buffer that will be holding ASCII character data of the string on top of background - * OUTPUTS: none - * RETURN VALUE: none - * SIDE EFFECTS: buffer now holds the ASCII character data of the string - * - */ -void string_to_buf_fruit(const char* string, unsigned char* fruit_buffer){ - int i,j,k; /* index for loop */ - unsigned char tmp_mask[TXT_X_DIM*TXT_Y_DIM]; /* buffer with masking data */ - unsigned char* current_character; /* holder for each string data*/ - int str_len = strlen(string); /* length of input string*/ - int idx = 0; /* index for inputting appropriate color data into buffer*/ - int center_offset = (TXT_X_DIM - str_len*FONT_WIDTH)/2; /* center offset calculation*/ - int mask = 0x80; /* masking value */ - - - - /* fill the buffer with background color*/ - for(i = 0; i < TXT_X_DIM*TXT_Y_DIM ;i++){ - tmp_mask[i] = 0; - } - /*compare bit value of each string and store them into the image_buffer*/ - for(i = 0; i < str_len; i++){ - int font_index = (int)string[i]; - current_character = font_data[font_index]; - for(j = 0; j < FONT_HEIGHT ; j++){ - mask = 0x80; - for(k = 0; k < FONT_WIDTH ; k++){ - - /* calculate index using offset, size of status barm and size of font */ - idx = TXT_X_DIM + center_offset + j * TXT_X_DIM + k + i * FONT_WIDTH; - /* populate buffer with 1 when string is located for masking purpose*/ - if(current_character[j] & mask) { - tmp_mask[idx] = 1; - } - mask = mask >> 1; - - } - } - } - - /* using mask buffer that contains string data, write on input buffer with transparent color */ - for(i = 0; i < TXT_Y_DIM ;i++){ - for(j = 0; j < TXT_X_DIM;j++){ - if(tmp_mask[ j + i * TXT_X_DIM] !=0){ - fruit_buffer[j + i * TXT_X_DIM] += T_OFFSET; - } - } - } -} diff --git a/mp2/text.h b/mp2/text.h deleted file mode 100644 index 9b1f3ca..0000000 --- a/mp2/text.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * tab:4 - * - * text.h - font data and text to mode X conversion utility header file - * - * "Copyright (c) 2004-2009 by Steven S. Lumetta." - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO - * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL - * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR - * THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - * - * Author: Steve Lumetta - * Version: 2 - * Creation Date: Thu Sep 9 22:08:16 2004 - * Filename: text.h - * History: - * SL 1 Thu Sep 9 22:08:16 2004 - * First written. - * SL 2 Sat Sep 12 13:40:11 2009 - * Integrated original release back into main code base. - */ - -#ifndef TEXT_H -#define TEXT_H - -/* The default VGA text mode font is 8x16 pixels. */ -#define FONT_WIDTH 8 -#define FONT_HEIGHT 16 - -/* status bar dimension */ -#define STATUS_X_DIM 320 -#define STATUS_Y_DIM 18 -#define T_OFFSET 0x40 -#define BLACK 0x00 - -#define TXT_X_DIM 104 /* max length of fruit string */ -#define TXT_Y_DIM 16 /* height of fruit string */ -/* Standard VGA text font. */ -extern unsigned char font_data[256][16]; -/* convert input string data into buffer holding ASCII data of the input string */ -void string_to_buf(const char* string, unsigned char* image_buffer, int background_color); - -/* convert input string into masking buffer and using that buffer to populate input image buffer with string data */ -void string_to_buf_fruit(const char* string, unsigned char* fruit_buffer); - -#endif /* TEXT_H */ diff --git a/mp3-LOS/INSTALL b/mp3-LOS/INSTALL deleted file mode 100644 index ac0d6ae..0000000 --- a/mp3-LOS/INSTALL +++ /dev/null @@ -1 +0,0 @@ -See the INSTALL file in the student-distrib/ directory. diff --git a/mp3-LOS/README.md b/mp3-LOS/README.md deleted file mode 100644 index f44ba6f..0000000 --- a/mp3-LOS/README.md +++ /dev/null @@ -1,70 +0,0 @@ -ACADEMIC INTEGRITY ------ -Please review the University of Illinois Student Code before starting, -particularly all subsections of Article 1, Part 4 Academic Integrity and Procedure [here](http://studentcode.illinois.edu/article1_part4_1-401.html). - -**§ 1‑402 Academic Integrity Infractions** - -(a). Cheating. No student shall use or attempt to use in any academic exercise materials, information, study aids, or electronic data that the student knows or should know is unauthorized. Instructors are strongly encouraged to make in advance a clear statement of their policies and procedures concerning the use of shared study aids, examination files, and related materials and forms of assistance. Such advance notification is especially important in the case of take-home examinations. During any examination, students should assume that external assistance (e.g., books, notes, calculators, and communications with others) is prohibited unless specifically authorized by the Instructor. A violation of this section includes but is not limited to: - -(1) Allowing others to conduct research or prepare any work for a student without prior authorization from the Instructor, including using the services of commercial term paper companies. - -(2) Submitting substantial portions of the same academic work for credit more than once or by more than one student without authorization from the Instructors to whom the work is being submitted. - -(3) Working with another person without authorization to satisfy an individual assignment. - -(b) Plagiarism. No student shall represent the words, work, or ideas of another as his or her own in any academic endeavor. A violation of this section includes but is not limited to: - -(1) Copying: Submitting the work of another as one’s own. - -(2) Direct Quotation: Every direct quotation must be identified by quotation marks or by appropriate indentation and must be promptly cited. Proper citation style for many academic departments is outlined in such manuals as the MLA Handbook or K.L. Turabian’s A Manual for Writers of Term Papers, Theses and Dissertations. These and similar publications are available in the University bookstore or library. The actual source from which cited information was obtained should be acknowledged. - -(3) Paraphrase: Prompt acknowledgment is required when material from another source is paraphrased or summarized in whole or in part. This is true even if the student’s words differ substantially from those of the source. A citation acknowledging only a directly quoted statement does not suffice as an acknowledgment of any preceding or succeeding paraphrased material. - -(4) Borrowed Facts or Information: Information obtained in one’s reading or research that is not common knowledge must be acknowledged. Examples of common knowledge might include the names of leaders of prominent nations, basic scientific laws, etc. Materials that contribute only to one’s general understanding of the subject may be acknowledged in a bibliography and need not be immediately cited. One citation is usually sufficient to acknowledge indebtedness when a number of connected sentences in the paper draw their special information from one source. - -(c) Fabrication. No student shall falsify or invent any information or citation in an academic endeavor. A violation of this section includes but is not limited to: - -(1) Using invented information in any laboratory experiment or other academic endeavor without notice to and authorization from the Instructor or examiner. It would be improper, for example, to analyze one sample in an experiment and covertly invent data based on that single experiment for several more required analyses. - -(2) Altering the answers given for an exam after the examination has been graded. - -(3) Providing false or misleading information for the purpose of gaining an academic advantage. - -(d) Facilitating Infractions of Academic Integrity. No student shall help or attempt to help another to commit an infraction of academic integrity, where one knows or should know that through one’s acts or omissions such an infraction may be facilitated. A violation of this section includes but is not limited to: - -(1) Allowing another to copy from one’s work. - -(2) Taking an exam by proxy for someone else. This is an infraction of academic integrity on the part of both the student enrolled in the course and the proxy or substitute. - -(3) Removing an examination or quiz from a classroom, faculty office, or other facility without authorization. - -(e) Bribes, Favors, and Threats. No student shall bribe or attempt to bribe, promise favors to or make threats against any person with the intent to affect a record of a grade or evaluation of academic performance. This includes conspiracy with another person who then takes the action on behalf of the student. - -(f) Academic Interference. No student shall tamper with, alter, circumvent, or destroy any educational material or resource in a manner that deprives any other student of fair access or reasonable use of that material or resource. - -(1) Educational resources include but are not limited to computer facilities, electronic data, required/reserved readings, reference works, or other library materials. - -(2) Academic interference also includes acts in which the student committing the infraction personally benefits from the interference, regardless of the effect on other students. - - -LEGAL ------ -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose, without fee, and without written agreement is -hereby granted, provided that the above copyright notice and the following -two paragraphs appear in all copies of this software. - -IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO -ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - -THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE - -PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR -THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, -SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." diff --git a/mp3-LOS/buglog b/mp3-LOS/buglog deleted file mode 100644 index 8a1d6e2..0000000 --- a/mp3-LOS/buglog +++ /dev/null @@ -1,51 +0,0 @@ -Date, Bug : Solution - -03/17, GDT unable to load undefined reference on gdt_desc: - gdt_desc need to be created in x86_desc.S. Using the struct declared in x86_desc.h does not work - - -03/18, As for naming in C, variable should not begin with number - -3/19, OS was crashing when rtc handler was run: - We were negating a value that was being pushed to the slave PIC. We got rid of the negation. - -3/25 page fault, because out of buffer range - - -4/8 page fault in execute system call, caused by read_data length argument being passed as a pointer instead of a uint32 -4/8 It kept calling terminal read, this is because terminal read was not set up to poll. - -4/13 page fault, read_file_by_name was given wrong length pointer. - Needed to &length in order to pass the address and prevent illegal memory access -4/13 Terminal read was reading each key twice (abc -> aabbcc), this is because the kbd interupt handler was pushing keys - regardless of whether or not it was the pressed or released scancode. -4/13 eax value was pushed and poped so we cannot get correct return value - -4/13 devel crashes after flushing tlb. - Incorrect pid passed into PDE macro - -4/14 in cp2 I wrote directory name start from the end of buf for the sake of alignment, while in cp4 dread cannot ouput files except verylarge... - -4/20 Biggest bug finished, we wrongly wrote SET_IDT_ENTRY(idt[0x28], rtc_interrupt_linkage); to use handler instead - -4/20 syserr fixed, since we have not set eax to -1 - -4/26 vidmap fixed. delete & before page table - -4/26 halt fixed. Removed by refrence operators in flush TLB inline assembly. Also changed how tss.esp0 is calculated. - -4/27 terminal switch print position error. - record screen position for every terminal. - -4/27 remap video memory in execute to fix fish page fault in terminal0 - -4/28 grep fixed since rtc_read wrongly return 1. - -4/28 cat fixed since terminal read breaks loop wrongly. - -4/28 fish only running on first terminal. Pingpong and counter were always running no matter what terminal they started in. - We hadn't properly implemented terminal switching, we still needed to have processes pause and resume when a terminal switch happened. - We finished context switching in the terminal_switch function to make solve this issue. - -4/28 CTRL + L was not working anymore. In the clear command we were using the wrong flag, so we switched that. - -4/28 Keyboard buffer overflow wasn't being handled well, we changed it to no longer take any more inputs, but still be able to be used as an input. \ No newline at end of file diff --git a/mp3-LOS/createfs b/mp3-LOS/createfs deleted file mode 100644 index 84f0238..0000000 Binary files a/mp3-LOS/createfs and /dev/null differ diff --git a/mp3-LOS/elfconvert b/mp3-LOS/elfconvert deleted file mode 100644 index 69cc472..0000000 Binary files a/mp3-LOS/elfconvert and /dev/null differ diff --git a/mp3-LOS/fish/Makefile b/mp3-LOS/fish/Makefile deleted file mode 100644 index eb1cb22..0000000 --- a/mp3-LOS/fish/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -all: fish - -# Note that you must be superuser to run the emulated version of the -# program. - -fish_emulated: fish.o blink.o ece391emulate.o ece391support.o - gcc -nostdlib -lc -g -o fish_emulated fish.o blink.o ece391emulate.o ece391support.o - -fish: fish.exe - ../elfconvert fish.exe - mv fish.exe.converted fish - -fish.exe: fish.o blink.o ece391support.o ece391syscall.o - gcc -nostdlib -g -o fish.exe fish.o blink.o ece391syscall.o ece391support.o - -%.o: %.S - gcc -nostdlib -c -Wall -g -D_USERLAND -D_ASM -o $@ $< - -%.o: %.c - gcc -nostdlib -Wall -c -g -o $@ $< - -clean:: - rm -f *.o *~ -clear: clean - rm -f fish fish.exe fish_emulated diff --git a/mp3-LOS/fish/blink.S b/mp3-LOS/fish/blink.S deleted file mode 100644 index bdf102f..0000000 --- a/mp3-LOS/fish/blink.S +++ /dev/null @@ -1,381 +0,0 @@ - -.data # section declaration - - # Useful offset constants for accessing members of a - # struct mp1_blink_struct structure - LOCATION = 0 - ON_CHAR = 2 - OFF_CHAR = 3 - ON_LENGTH = 4 - OFF_LENGTH = 6 - COUNTDOWN = 8 - STATUS = 10 - NEXT = 12 - - STRUCT_SIZE = 16 - -# Pointer to head of list (initialized to NULL) -mp1_list_head: - .long 0 - -call_table: - .long mp1_ioctl_add - .long mp1_ioctl_remove - .long mp1_ioctl_find - .long mp1_ioctl_sync - -.text # section declaration - -# Export the function symbol names - -.global mp1_rtc_tasklet -.global mp1_ioctl - -# void mp1_poke(void); -# -# Interface: Register-based arguments (not C-style) -# Inputs: %cl - The byte you wish to write -# %eax - Offset from the start of video memory that you wish -# to write to -# Outputs: Text-mode video screen is written to at location %eax with -# the byte in %cl -# Registers: Clobbers EDX -mp1_poke: - - movl vmem_base_addr(,1),%edx - movb %cl,(%edx,%eax,1) - ret - -mp1_rtc_tasklet: - - pushl %ebp - movl %esp, %ebp - - pushl %esi - pushl %edi - pushl %ebx - - movl mp1_list_head, %ebx - -tasklet_loop: - cmpl $0, %ebx - je tasklet_end - - decw COUNTDOWN(%ebx) - cmpw $0,COUNTDOWN(%ebx) - jg next_loop - - movzwl LOCATION(%ebx), %eax #blink location is now in eax - shl $1,%eax - - testw $0x1,STATUS(%ebx) - jz currently_off - - movb OFF_CHAR(%ebx), %cl - call mp1_poke - movw OFF_LENGTH(%ebx),%dx - jmp end_blink - -currently_off: - movb ON_CHAR(%ebx), %cl - call mp1_poke - movw ON_LENGTH(%ebx),%dx - -end_blink: - movw %dx, COUNTDOWN(%ebx) - xorw $0x1, STATUS(%ebx) - -next_loop: - movl NEXT(%ebx), %ebx - jmp tasklet_loop - -tasklet_end: - - popl %ebx - popl %edi - popl %esi - - popl %ebp - ret - -mp1_ioctl: - movl 8(%esp), %eax - jmp *call_table(,%eax,4) - -mp1_ioctl_add: - pushl %ebp - movl %esp, %ebp - - # Allocate temp structure on the stack - subl $STRUCT_SIZE, %esp - - # Preserve registers - pushl %esi - pushl %edi - pushl %ebx - - # Get pointer to temp structure - leal -STRUCT_SIZE(%ebp), %ebx - - # Copy user data onto the stack - pushl $STRUCT_SIZE - pushl 8(%ebp) - pushl %ebx - call ece391_memcpy - addl $12,%esp - - # Check that the copy succeeded - cmpl $0,%eax - jne add_fail_return - - # Check that the location is valid - cmpw $80*25,LOCATION(%ebx) - jae add_fail_return - - # Mark this structure as valid - movw $0x1,STATUS(%ebx) # Mark it as on - movw ON_LENGTH(%ebx),%dx - movw %dx,COUNTDOWN(%ebx) - - # Allocate some memory, pointer returned in EAX - pushl $STRUCT_SIZE - call mp1_malloc - add $4, %esp - cmpl $0, %eax - je add_fail_return - - # Save EAX - pushl %eax - - pushl $STRUCT_SIZE - pushl %ebx - pushl %eax - call ece391_memcpy - addl $12, %esp - - # Restore the value from EAX into EDX - popl %edx - - # Insert this new item at the front of the list - movl mp1_list_head, %eax - movl %eax, NEXT(%edx) - movl %edx, mp1_list_head - -display: - # Display the character - movzwl LOCATION(%edx),%eax - shll $1,%eax - movb ON_CHAR(%edx),%cl - call mp1_poke - jmp add_success_return - -add_fail_return: - movl $-1,%eax - jmp add_leave - -add_success_return: - movl $0, %eax -add_leave: - popl %ebx - popl %edi - popl %esi - - leave - ret - - -mp1_ioctl_remove: - pushl %ebp - movl %esp, %ebp - - pushl %esi - pushl %edi - pushl %ebx - - pushl 8(%ebp) - call mp1_find_helper - addl $4, %esp - cmpl $0, %eax - je remove_fail_return - - # Found the right element. Now find the - # previous pointer in the list, and remove it - # We should not fail here, because mp1_find_helper - # returned a valid list element - - leal mp1_list_head, %edx -remove_find_prev: - cmp %eax, (%edx) - je found_prev - movl (%edx), %edx - leal NEXT(%edx), %edx - jmp remove_find_prev - -found_prev: - # Perform the removal - movl NEXT(%eax), %ecx - movl %ecx, (%edx) - -free_mem: - pushl %eax - call mp1_free - addl $4, %esp - jmp remove_success_return - -remove_fail_return: - movl $-1,%eax - jmp remove_leave - -remove_success_return: - movl $0, %eax -remove_leave: - popl %ebx - popl %edi - popl %esi - - leave - ret - - -mp1_ioctl_sync: - pushl %ebp - movl %esp, %ebp - - pushl %esi - pushl %edi - pushl %ebx - -sync_find_first: - movl 8(%ebp), %eax - shr $16, %eax - pushl %eax - call mp1_find_helper - addl $4, %esp - cmpl $0, %eax - je sync_fail_return - movl %eax, %esi - - movl 8(%ebp), %eax - andl $0xFFFF, %eax - pushl %eax - call mp1_find_helper - addl $4, %esp - cmpl $0, %eax - je sync_fail_return - movl %eax, %edi - -sync_copy_loop: - movw ON_LENGTH(%esi), %ax - movw %ax, ON_LENGTH(%edi) - movw OFF_LENGTH(%esi), %ax - movw %ax, OFF_LENGTH(%edi) - movw COUNTDOWN(%esi), %ax - movw %ax, COUNTDOWN(%edi) - movw STATUS(%esi), %ax - movw %ax, STATUS(%edi) - - movzwl LOCATION(%edi), %eax - shll $1,%eax - movzbl OFF_CHAR(%edi),%ecx - movzbl ON_CHAR(%edi),%ebx - testb $0x1,STATUS(%edi) - cmovl %ebx, %ecx - -sync_display: - call mp1_poke - jmp sync_success_return - -sync_fail_return: - movl $-1,%eax - jmp sync_leave - -sync_success_return: - movl $0, %eax -sync_leave: - popl %ebx - popl %edi - popl %esi - - leave - ret - -mp1_ioctl_find: - pushl %ebp - movl %esp, %ebp - subl $2,%esp - - pushl %esi - pushl %edi - pushl %ebx - - pushl $2 - pushl 8(%ebp) - leal -2(%ebp),%edi - pushl %edi - call ece391_memcpy - addl $12,%esp - - cmp $0,%eax - jne find_fail_return - - movzwl -2(%ebp),%eax - pushl %eax - call mp1_find_helper - addl $4, %esp - cmpl $0, %eax - je find_fail_return - - pushl $STRUCT_SIZE - pushl %eax - pushl 8(%ebp) - call ece391_memcpy - addl $12,%esp - - cmp $0,%eax - je find_success_return - -find_fail_return: - movl $-1,%eax - jmp find_leave - -find_success_return: - movl $0, %eax -find_leave: - popl %ebx - popl %edi - popl %esi - - leave - ret - -mp1_find_helper: - pushl %ebp - movl %esp, %ebp - - pushl %ebx - - movw 8(%ebp), %ax - movl mp1_list_head, %ebx -loop: - cmpl $0, %ebx - je helper_fail_return - - cmpw %ax, LOCATION(%ebx) - je helper_success_return - - movl NEXT(%ebx), %ebx - jmp loop - -helper_fail_return: - xorl %eax, %eax - jmp helper_leave - -helper_success_return: - movl %ebx, %eax - -helper_leave: - popl %ebx - leave - ret - -.end diff --git a/mp3-LOS/fish/blink.h b/mp3-LOS/fish/blink.h deleted file mode 100644 index cf7690e..0000000 --- a/mp3-LOS/fish/blink.h +++ /dev/null @@ -1,15 +0,0 @@ -#define RTC_ADD 0 -#define RTC_REMOVE 1 -#define RTC_FIND 2 -#define RTC_SYNC 3 - -struct mp1_blink_struct { - unsigned short location; - char on_char; - char off_char; - unsigned short on_length; - unsigned short off_length; - unsigned short countdown; - unsigned short status; - struct mp1_blink_struct* next; -} __attribute((packed)); diff --git a/mp3-LOS/fish/ece391emulate.c b/mp3-LOS/fish/ece391emulate.c deleted file mode 100644 index 76a422a..0000000 --- a/mp3-LOS/fish/ece391emulate.c +++ /dev/null @@ -1,227 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "ece391support.h" -#include "ece391syscall.h" -#include "ece391sysnum.h" - - -static uint32_t start_esp; -static int32_t dir_fd = -1; -static DIR* dir = NULL; - - -/* - * (copied from the real system call support) - * - * Rather than create a case for each number of arguments, we simplify - * and use one macro for up to three arguments; the system calls should - * ignore the other registers, and they're caller-saved anyway. - */ -#define DO_CALL(name,number) \ -asm volatile (" \ -.GLOBL " #name " ;\ -" #name ": ;\ - PUSHL %EBX ;\ - MOVL $" #number ",%EAX ;\ - MOVL 8(%ESP),%EBX ;\ - MOVL 12(%ESP),%ECX ;\ - MOVL 16(%ESP),%EDX ;\ - INT $0x80 ;\ - CMP $0xFFFFC000,%EAX ;\ - JBE 1f ;\ - MOVL $-1,%EAX ;\ -1: POPL %EBX ;\ - RET \ -") - -/* these wrappers require no changes */ -extern int32_t __ece391_read (int32_t fd, void* buf, int32_t nbytes); -extern int32_t __ece391_write (int32_t fd, const void* buf, int32_t nbytes); -extern int32_t __ece391_close (int32_t fd); -void fake_function () { -DO_CALL(ece391_halt,1 /* SYS_HALT */); -DO_CALL(__ece391_read,3 /* SYS_READ */); -DO_CALL(__ece391_write,4 /* SYS_WRITE */); -DO_CALL(__ece391_close,6 /* SYS_CLOSE */); - -/* Call the main() function, then halt with its return value. */ - -asm volatile (" \n\ -.GLOBAL _start \n\ -_start: \n\ - MOVL %ESP,start_esp \n\ - CALL main \n\ - PUSHL %EAX \n\ - CALL ece391_halt \n\ -"); - -/* end of fake container function */ -} - -int32_t -ece391_execute (const uint8_t* command) -{ - int status; - uint8_t buf[1026]; - char* args[1024]; - uint8_t* scan; - uint32_t n_arg; - - if (1023 < ece391_strlen (command)) - return -1; - buf[0] = '.'; - buf[1] = '/'; - ece391_strcpy (buf + 2, command); - for (scan = buf + 2; '\0' != *scan && ' ' != *scan && '\n' != *scan; - scan++); - args[0] = (char*)buf; - n_arg = 1; - if ('\0' != *scan) { - *scan++ = '\0'; - /* parse arguments */ - while (1) { - while (' ' == *scan) scan++; - if ('\0' == *scan || '\n' == *scan) { - *scan = '\0'; - break; - } - args[n_arg++] = (char*)scan; - while ('\0' != *scan && ' ' != *scan && '\n' != *scan) scan++; - if ('\0' != *scan) - *scan++ = '\0'; - } - } - args[n_arg] = NULL; - if (0 == fork ()) { - execv ((char*)buf, args); - kill (getpid (), 9); - } - (void)wait (&status); - if (WIFEXITED (status)) - return WEXITSTATUS (status); - if (9 == WTERMSIG (status)) - return -1; - return 256; -} - -int32_t -ece391_open (const uint8_t* filename) -{ - uint32_t rval; - - if (0 == ece391_strcmp (filename, (uint8_t*)".")) { - dir = opendir ("."); - dir_fd = open ("/dev/null", O_RDONLY); - return dir_fd; - } - - asm volatile ("INT $0x80" : "=a" (rval) : - "a" (5), "b" (filename), "c" (O_RDONLY)); - if (rval > 0xFFFFC000) - return -1; - return rval; -} - -int32_t -ece391_getargs (uint8_t* buf, int32_t nbytes) -{ - int32_t argc = *(uint32_t*)start_esp; - uint8_t** argv = (uint8_t**)(start_esp + 4); - int32_t idx, len; - - idx = 1; - while (idx < argc) { - len = ece391_strlen (argv[idx]); - if (len > nbytes) - return -1; - ece391_strcpy (buf, argv[idx]); - buf += len; - nbytes -= len; - if (++idx >= argc) - break; - if (nbytes < 1) - return -1; - *buf++ = ' '; - nbytes--; - } - if (nbytes < 1) - return -1; - *buf = '\0'; - return 0; -} - -int32_t -ece391_vidmap (uint8_t** screen_start) -{ - static int mem_fd = -1; - void* mem_image; - - if(mem_fd == -1) { - mem_fd = open ("/dev/mem", O_RDWR); - } - - if ((mem_image = mmap((void*)0, 1024*1024, PROT_READ | PROT_WRITE, - MAP_SHARED, mem_fd, 0)) == MAP_FAILED) { - perror ("mmap low memory"); - return -1; - } - - *screen_start = (uint8_t*)(mem_image + 0xb8000); - return 0; -} - -int32_t -ece391_read (int32_t fd, void* buf, int32_t nbytes) -{ - struct dirent* de; - int32_t copied; - uint8_t* from; - uint8_t* to; - - if (NULL == dir || dir_fd != fd) - return __ece391_read (fd, buf, nbytes); - if (NULL == (de = readdir (dir))) - return 0; - to = buf; - from = (uint8_t*)de->d_name; - copied = 0; - while ('\0' != *from) { - *to++ = *from++; - if (++copied == nbytes) - return nbytes; - if (32 == copied) - return 32; - } - while (nbytes > copied && 32 > copied) { - *to++ = '\0'; - copied++; - } - return copied; -} - -int32_t -ece391_write (int32_t fd, const void* buf, int32_t nbytes) -{ - if (NULL == dir || dir_fd != fd) - return __ece391_write (fd, buf, nbytes); - return -1; -} - -int32_t -ece391_close (int32_t fd) -{ - if (NULL == dir || dir_fd != fd) - return __ece391_close (fd); - (void)closedir (dir); - dir = NULL; - (void)close (dir_fd); - dir_fd = -1; - return 0; -} - diff --git a/mp3-LOS/fish/ece391support.c b/mp3-LOS/fish/ece391support.c deleted file mode 100644 index b264fb0..0000000 --- a/mp3-LOS/fish/ece391support.c +++ /dev/null @@ -1,53 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - - -uint32_t -ece391_strlen (const uint8_t* s) -{ - uint32_t len; - - for (len = 0; '\0' != *s; s++, len++); - return len; -} - -void -ece391_strcpy (uint8_t* dst, const uint8_t* src) -{ - while ('\0' != (*dst++ = *src++)); -} - -void -ece391_fdputs (int32_t fd, const uint8_t* s) -{ - (void)ece391_write (fd, s, ece391_strlen (s)); -} - -int32_t -ece391_strcmp (const uint8_t* s1, const uint8_t* s2) -{ - while (*s1 == *s2) { - if (*s1 == '\0') - return 0; - s1++; - s2++; - } - return ((int32_t)*s1) - ((int32_t)*s2); -} - -int32_t -ece391_strncmp (const uint8_t* s1, const uint8_t* s2, uint32_t n) -{ - if (0 == n) - return 0; - while (*s1 == *s2) { - if (*s1 == '\0' || --n == 0) - return 0; - s1++; - s2++; - } - return ((int32_t)*s1) - ((int32_t)*s2); -} - diff --git a/mp3-LOS/fish/ece391support.h b/mp3-LOS/fish/ece391support.h deleted file mode 100644 index a0664c0..0000000 --- a/mp3-LOS/fish/ece391support.h +++ /dev/null @@ -1,10 +0,0 @@ -#if !defined(ECE391SUPPORT_H) -#define ECE391SUPPORT_H - -extern uint32_t ece391_strlen (const uint8_t* s); -extern void ece391_strcpy (uint8_t* dst, const uint8_t* src); -extern void ece391_fdputs (int32_t fd, const uint8_t* s); -extern int32_t ece391_strcmp (const uint8_t* s1, const uint8_t* s2); -extern int32_t ece391_strncmp (const uint8_t* s1, const uint8_t* s2, uint32_t n); - -#endif /* ECE391SUPPORT_H */ diff --git a/mp3-LOS/fish/ece391syscall.S b/mp3-LOS/fish/ece391syscall.S deleted file mode 100644 index a17c6b8..0000000 --- a/mp3-LOS/fish/ece391syscall.S +++ /dev/null @@ -1,41 +0,0 @@ -#include "ece391sysnum.h" - -/* - * Rather than create a case for each number of arguments, we simplify - * and use one macro for up to three arguments; the system calls should - * ignore the other registers, and they're caller-saved anyway. - */ -#define DO_CALL(name,number) \ -.GLOBL name ;\ -name: PUSHL %EBX ;\ - MOVL $number,%EAX ;\ - MOVL 8(%ESP),%EBX ;\ - MOVL 12(%ESP),%ECX ;\ - MOVL 16(%ESP),%EDX ;\ - INT $0x80 ;\ - POPL %EBX ;\ - RET - -/* the system call library wrappers */ -DO_CALL(ece391_halt,SYS_HALT) -DO_CALL(ece391_execute,SYS_EXECUTE) -DO_CALL(ece391_read,SYS_READ) -DO_CALL(ece391_write,SYS_WRITE) -DO_CALL(ece391_open,SYS_OPEN) -DO_CALL(ece391_close,SYS_CLOSE) -DO_CALL(ece391_getargs,SYS_GETARGS) -DO_CALL(ece391_vidmap,SYS_VIDMAP) -DO_CALL(ece391_set_handler,SYS_SET_HANDLER) -DO_CALL(ece391_sigreturn,SYS_SIGRETURN) - - -/* Call the main() function, then halt with its return value. */ - -.GLOBAL _start -_start: - CALL main - PUSHL $0 - PUSHL $0 - PUSHL %EAX - CALL ece391_halt - diff --git a/mp3-LOS/fish/ece391syscall.h b/mp3-LOS/fish/ece391syscall.h deleted file mode 100644 index 70883b7..0000000 --- a/mp3-LOS/fish/ece391syscall.h +++ /dev/null @@ -1,24 +0,0 @@ -#if !defined(ECE391SYSCALL_H) -#define ECE391SYSCALL_H - -#include - -/* All calls return >= 0 on success or -1 on failure. */ - -/* - * Note that the system call for halt will have to make sure that only - * the low byte of EBX (the status argument) is returned to the calling - * task. Negative returns from execute indicate that the desired program - * could not be found. - */ -extern int32_t ece391_halt (uint8_t status); -extern int32_t ece391_execute (const uint8_t* command); -extern int32_t ece391_read (int32_t fd, void* buf, int32_t nbytes); -extern int32_t ece391_write (int32_t fd, const void* buf, int32_t nbytes); -extern int32_t ece391_open (const uint8_t* filename); -extern int32_t ece391_close (int32_t fd); -extern int32_t ece391_getargs (uint8_t* buf, int32_t nbytes); -extern int32_t ece391_vidmap (uint8_t** screen_start); - -#endif /* ECE391SYSCALL_H */ - diff --git a/mp3-LOS/fish/ece391sysnum.h b/mp3-LOS/fish/ece391sysnum.h deleted file mode 100644 index 052f3b2..0000000 --- a/mp3-LOS/fish/ece391sysnum.h +++ /dev/null @@ -1,15 +0,0 @@ -#if !defined(ECE391SYSNUM_H) -#define ECE391SYSNUM_H - -#define SYS_HALT 1 -#define SYS_EXECUTE 2 -#define SYS_READ 3 -#define SYS_WRITE 4 -#define SYS_OPEN 5 -#define SYS_CLOSE 6 -#define SYS_GETARGS 7 -#define SYS_VIDMAP 8 -#define SYS_SET_HANDLER 9 -#define SYS_SIGRETURN 10 - -#endif /* ECE391SYSNUM_H */ diff --git a/mp3-LOS/fish/fish.c b/mp3-LOS/fish/fish.c deleted file mode 100644 index 6d2e5d8..0000000 --- a/mp3-LOS/fish/fish.c +++ /dev/null @@ -1,196 +0,0 @@ -#include -#include "ece391support.h" -#include "ece391syscall.h" -#include "blink.h" - -#define NULL 0 -#define WAIT 100 -uint8_t *vmem_base_addr; -uint8_t *mp1_set_video_mode (void); -void add_frames(uint8_t *, uint8_t *, int32_t); -void ece391_memset(void* memory, char c, int n); -int32_t ece391_memcpy(void* dest, const void* src, int32_t n); - -uint8_t file0[] = "frame0.txt"; -uint8_t file1[] = "frame1.txt"; - -/* Extern the externally-visible MP1 functions */ -extern int mp1_ioctl(unsigned long arg, unsigned long cmd); -extern void mp1_rtc_tasklet(unsigned long trash); - -static struct mp1_blink_struct blink_array[80*25]; - -int main(void) -{ - int rtc_fd, ret_val, i, garbage; - struct mp1_blink_struct blink_struct; - - ece391_memset(blink_array, 0, sizeof(struct mp1_blink_struct)*80*25); - - if(mp1_set_video_mode() == NULL) { - return -1; - } - - rtc_fd = ece391_open((uint8_t*)"rtc"); - - add_frames(file0, file1, rtc_fd); - - ret_val = 32; - ret_val = ece391_write(rtc_fd, &ret_val, 4); - - for(i=0; i \| \ / - |/\_/ |/ |/ -----------M----M-------- diff --git a/mp3-LOS/fish/frame1.txt b/mp3-LOS/fish/frame1.txt deleted file mode 100644 index eafbe6c..0000000 --- a/mp3-LOS/fish/frame1.txt +++ /dev/null @@ -1,11 +0,0 @@ -\/\/\/\/\/\/\/\/\/\/\/\/ - o o - o - o - o o - - _ / - |\/.\ \ \/ \ / - |= _> \ \ \| - |/\_> |/ |/ -----------M----M-------- diff --git a/mp3-LOS/fsdir/cat b/mp3-LOS/fsdir/cat deleted file mode 100644 index aa7ac9b..0000000 Binary files a/mp3-LOS/fsdir/cat and /dev/null differ diff --git a/mp3-LOS/fsdir/counter b/mp3-LOS/fsdir/counter deleted file mode 100644 index 549768c..0000000 Binary files a/mp3-LOS/fsdir/counter and /dev/null differ diff --git a/mp3-LOS/fsdir/fish b/mp3-LOS/fsdir/fish deleted file mode 100644 index e2d43e8..0000000 Binary files a/mp3-LOS/fsdir/fish and /dev/null differ diff --git a/mp3-LOS/fsdir/frame0.txt b/mp3-LOS/fsdir/frame0.txt deleted file mode 100644 index e618dd8..0000000 --- a/mp3-LOS/fsdir/frame0.txt +++ /dev/null @@ -1,11 +0,0 @@ -/\/\/\/\/\/\/\/\/\/\/\/\ - o - o o - o - o - o O - _ \ - |\/.\ | \/ / / - |= _> \| \ / - |/\_/ |/ |/ -----------M----M-------- diff --git a/mp3-LOS/fsdir/frame1.txt b/mp3-LOS/fsdir/frame1.txt deleted file mode 100644 index eafbe6c..0000000 --- a/mp3-LOS/fsdir/frame1.txt +++ /dev/null @@ -1,11 +0,0 @@ -\/\/\/\/\/\/\/\/\/\/\/\/ - o o - o - o - o o - - _ / - |\/.\ \ \/ \ / - |= _> \ \ \| - |/\_> |/ |/ -----------M----M-------- diff --git a/mp3-LOS/fsdir/grep b/mp3-LOS/fsdir/grep deleted file mode 100644 index b785b70..0000000 Binary files a/mp3-LOS/fsdir/grep and /dev/null differ diff --git a/mp3-LOS/fsdir/hello b/mp3-LOS/fsdir/hello deleted file mode 100644 index 80fff89..0000000 Binary files a/mp3-LOS/fsdir/hello and /dev/null differ diff --git a/mp3-LOS/fsdir/ls b/mp3-LOS/fsdir/ls deleted file mode 100644 index 3dda063..0000000 Binary files a/mp3-LOS/fsdir/ls and /dev/null differ diff --git a/mp3-LOS/fsdir/pingpong b/mp3-LOS/fsdir/pingpong deleted file mode 100644 index 7b17147..0000000 Binary files a/mp3-LOS/fsdir/pingpong and /dev/null differ diff --git a/mp3-LOS/fsdir/shell b/mp3-LOS/fsdir/shell deleted file mode 100644 index 84c531e..0000000 Binary files a/mp3-LOS/fsdir/shell and /dev/null differ diff --git a/mp3-LOS/fsdir/sigtest b/mp3-LOS/fsdir/sigtest deleted file mode 100644 index 896c34f..0000000 Binary files a/mp3-LOS/fsdir/sigtest and /dev/null differ diff --git a/mp3-LOS/fsdir/syserr b/mp3-LOS/fsdir/syserr deleted file mode 100644 index 7d6c4c2..0000000 Binary files a/mp3-LOS/fsdir/syserr and /dev/null differ diff --git a/mp3-LOS/fsdir/testprint b/mp3-LOS/fsdir/testprint deleted file mode 100644 index 30c1ea0..0000000 Binary files a/mp3-LOS/fsdir/testprint and /dev/null differ diff --git a/mp3-LOS/fsdir/verylargetextwithverylongname.txt b/mp3-LOS/fsdir/verylargetextwithverylongname.txt deleted file mode 100644 index a5e31d9..0000000 --- a/mp3-LOS/fsdir/verylargetextwithverylongname.txt +++ /dev/null @@ -1,33 +0,0 @@ -very large text file with a very long name -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ -ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ -abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz -~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>? diff --git a/mp3-LOS/gitignore b/mp3-LOS/gitignore deleted file mode 100644 index 856138c..0000000 --- a/mp3-LOS/gitignore +++ /dev/null @@ -1,114 +0,0 @@ -# ECE 391 gitignore -# Author: Lavin Devnani (devnani2) -# -# Permission to use, copy, modify, and distribute this software and its -# documentation for any purpose, without fee, and without written agreement is -# hereby granted, provided that the above copyright notice and the following -# two paragraphs appear in all copies of this software. -# -# IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO -# ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL -# DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -# EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED -# OF THE POSSIBILITY OF SUCH DAMAGE. -# -# THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE -# PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR -# THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, -# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." -# - -# C - https://github.com/github/gitignore/blob/master/C.gitignore -# Prerequisites -*.d -*.DS_Store - -# Object files -*.o -*.ko -*.elf - -# Linker output -*.ilk -*.map -*.exp - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ -*.su -*.idb -*.pdb - -# Kernel Module Compile Results -*.mod* -*.cmd -.tmp_versions/ -modules.order -Module.symvers -Mkfile.old -dkms.conf - -# C++ - https://github.com/github/gitignore/blob/master/C%2B%2B.gitignore -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# 391 specific -*.qcow -source/ - diff --git a/mp3-LOS/student-distrib/DEBUG b/mp3-LOS/student-distrib/DEBUG deleted file mode 100644 index 59ee97a..0000000 --- a/mp3-LOS/student-distrib/DEBUG +++ /dev/null @@ -1,7 +0,0 @@ -DEBUGGING MP3 -=============== - -The only steps that need to be taken on the virtual machine for debugging -using qemu is to perform a "sudo make debug" (after "make dep"). This will build the disk image needed for QEMU and gdb. - -Refer to the handout for instructions on starting QEMU and gdb. diff --git a/mp3-LOS/student-distrib/INSTALL b/mp3-LOS/student-distrib/INSTALL deleted file mode 100644 index 90c3320..0000000 --- a/mp3-LOS/student-distrib/INSTALL +++ /dev/null @@ -1,17 +0,0 @@ -ECE391 MP3 - Operating System Project -===================================== - -To get this skeleton OS running on QEMU, you must do the following steps: - -"make dep" -"sudo make" - -to build the OS (it is called bootimg) and the QEMU disk image (mp3.img) - -You can then follow the instructions in Appendix G to setup your -debug.bat batch script. - -If you would like to run MP3 without having to connect gdb (When you are done -and have removed all your bugs for example), you can duplicate the debug.bat -batch script and remove the -s and -S options in the QEMU command. This is -will stop QEMU from waiting for GDB to connect. diff --git a/mp3-LOS/student-distrib/Makefile b/mp3-LOS/student-distrib/Makefile deleted file mode 100644 index fca08c3..0000000 --- a/mp3-LOS/student-distrib/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# Makefile for OS project -# To build, first `make dep`, them `make`. Everything should be automatic. -# Will compile all *.c and *.S files in the current directory. - - -# Flags to use when compiling, preprocessing, assembling, and linking -CFLAGS+=-Wall -fno-builtin -fno-stack-protector -nostdlib -ASFLAGS+= -LDFLAGS+=-nostdlib -static -CC=gcc - -#If you have any .h files in another directory, add -I to this line -CPPFLAGS+=-nostdinc -g - -# This generates the list of source files -SRC=$(wildcard *.S) $(wildcard *.c) $(wildcard */*.S) $(wildcard */*.c) - -# This generates the list of .o files. The order matters, boot.o must be first -OBJS=boot.o -OBJS+=$(filter-out boot.o,$(patsubst %.S,%.o,$(filter %.S,$(SRC)))) -OBJS+=$(patsubst %.c,%.o,$(filter %.c,$(SRC))) - -bootimg: Makefile $(OBJS) - rm -f bootimg - $(CC) $(LDFLAGS) $(OBJS) -Ttext=0x400000 -o bootimg - sudo ./debug.sh - -dep: Makefile.dep - -Makefile.dep: $(SRC) - $(CC) -MM $(CPPFLAGS) $(SRC) > $@ - -.PHONY: clean -clean: - rm -f *.o */*.o Makefile.dep - -ifneq ($(MAKECMDGOALS),dep) -ifneq ($(MAKECMDGOALS),clean) -include Makefile.dep -endif -endif diff --git a/mp3-LOS/student-distrib/boot.S b/mp3-LOS/student-distrib/boot.S deleted file mode 100644 index ee22b7b..0000000 --- a/mp3-LOS/student-distrib/boot.S +++ /dev/null @@ -1,58 +0,0 @@ -# boot.S - start point for the kernel after GRUB gives us control -# vim:ts=4 noexpandtab - -#define ASM 1 - -#include "multiboot.h" -#include "x86_desc.h" - -.text - - # Multiboot header (required for GRUB to boot us) - .long MULTIBOOT_HEADER_MAGIC - .long MULTIBOOT_HEADER_FLAGS - .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) - -# Entrypoint to the kernel -.globl start, _start - -.align 4 -start: -_start: - # Make sure interrupts are off - cli - jmp continue - -continue: - # Load the GDT - - lgdt gdt_desc - - # Load CS with the new descriptor value - ljmp $KERNEL_CS, $keep_going - -keep_going: - # Set up ESP so we can have an initial stack - movl $0x800000, %esp - - # Set up the rest of the segment selector registers - movw $KERNEL_DS, %cx - movw %cx, %ss - movw %cx, %ds - movw %cx, %es - movw %cx, %fs - movw %cx, %gs - - # Push the parameters that entry() expects (see kernel.c): - # eax = multiboot magic - # ebx = address of multiboot info struct - pushl %ebx - pushl %eax - - # Jump to the C entrypoint to the kernel. - call entry - - # We'll never get back here, but we put in a hlt anyway. -halt: - hlt - jmp halt diff --git a/mp3-LOS/student-distrib/bootimg b/mp3-LOS/student-distrib/bootimg deleted file mode 100644 index 8ae7a24..0000000 Binary files a/mp3-LOS/student-distrib/bootimg and /dev/null differ diff --git a/mp3-LOS/student-distrib/debug.h b/mp3-LOS/student-distrib/debug.h deleted file mode 100644 index aacc26d..0000000 --- a/mp3-LOS/student-distrib/debug.h +++ /dev/null @@ -1,33 +0,0 @@ -/* debug.h - Useful macros for debugging - * vim:ts=4 noexpandtab - */ - -#ifndef _DEBUG_H -#define _DEBUG_H - -#ifndef ASM - -#ifdef DEBUG - -#define ASSERT(EXP) \ -do { \ - if (!(EXP)) { \ - printf(__FILE__ ":%u: Assertion `" #EXP "\' failed.\n", __LINE__); \ - } \ -} while(0) - -#define debugf(...) \ -do { \ - printf(__FILE__ ":%u: ", __LINE__); \ - printf(__VA_ARGS__); \ -} while(0) - -#else -#define ASSERT(EXP) \ - while (0) -#define debugf(...) \ - while (0) -#endif - -#endif -#endif /* _DEBUG_H */ diff --git a/mp3-LOS/student-distrib/debug.sh b/mp3-LOS/student-distrib/debug.sh deleted file mode 100644 index 74bb305..0000000 --- a/mp3-LOS/student-distrib/debug.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -if [ -d /mnt/tmpmp3 ]; then - rm -rf /mnt/tmpmp3 -fi - -if [ -d /tmp/mp3 ]; then - rm -rf /tmp/mp3 -fi - -mkdir /mnt/tmpmp3 -mkdir /tmp/mp3 -cp ./bootimg /tmp/mp3/ -cp ./filesys_img /tmp/mp3/ -cp ./mp3.img /tmp/mp3/ -mount -o loop,offset=32256 /tmp/mp3/mp3.img /mnt/tmpmp3 -cp -f /tmp/mp3/bootimg /mnt/tmpmp3/ -cp -f /tmp/mp3/filesys_img /mnt/tmpmp3/ -umount /mnt/tmpmp3 -cp -f /tmp/mp3/mp3.img ./ -rm -rf /tmp/mp3 -rm -rf /mnt/tmpmp3 diff --git a/mp3-LOS/student-distrib/exceptions_linkage.S b/mp3-LOS/student-distrib/exceptions_linkage.S deleted file mode 100644 index eb43a7d..0000000 --- a/mp3-LOS/student-distrib/exceptions_linkage.S +++ /dev/null @@ -1,314 +0,0 @@ -#define vector0 0 -#define vector1 1 -#define vector2 2 -#define vector3 3 -#define vector4 4 -#define vector5 5 -#define vector6 6 -#define vector7 7 -#define vector8 8 -#define vector9 9 -#define vector10 10 -#define vector11 11 -#define vector12 12 -#define vector13 13 -#define vector14 14 -#define vector15 15 -#define vector16 16 -#define vector17 17 -#define vector18 18 -#define vector19 19 -#define vector33 33 -#define vector40 40 -/* Macro for saving all registers */ -#define SAVE_ALL \ - cld; \ - pushl %fs; \ - pushl %es; \ - pushl %ds; \ - pushl %ebp; \ - pushl %edi; \ - pushl %esi; \ - pushl %edx; \ - pushl %ecx; \ - pushl %ebx; \ - pushl %eax; \ - -.global pit_handler_linkage -.global page_fault_linkage -.global divide_error_linkage -.global debug_exception_linkage -.global nmi_interrupt_linkage -.global breakpoint_exception_linkage -.global overflow_exception_linkage -.global bound_re_linkage -.global invalid_opcode_linkage -.global device_na_linkage -.global double_fault_linkage -.global coprocessor_so_linkage -.global invalid_tss_linkage -.global segment_np_linkage -.global stack_fault_linkage -.global general_protection_linkage -.global reserved_exc_linkage -.global FPUfpe_linkage -.global alignment_check_linkage -.global machine_check_linkage -.global simd_fp_linkage -.global pit_linkage -.global keyboard_linkage -.global rtc_interrupt_linkage - - - -#define PUSHALL \ -pushl %gs ;\ -pushl %fs ;\ -pushl %es ;\ -pushl %ds ;\ -pushl %ebp ;\ -pushl %esi ;\ -pushl %edi ;\ -pushl %edx ;\ -pushl %ecx ;\ -pushl %ebx ;\ - -#define POPALL \ -popl %ebx ;\ -popl %ecx ;\ -popl %edx ;\ -popl %edi ;\ -popl %esi ;\ -popl %ebp ;\ -popl %ds ;\ -popl %es ;\ -popl %fs ;\ -popl %gs ;\ - -.global halt -.global execute -.global read -.global write -.global open -.global close -.global getargs -.global vidmap -.global set_handler -.global sigreturn -.global system_call_linkage - -system_call_jmp: - .long 0 - .long halt - .long execute - .long read - .long write - .long open - .long close - .long getargs - .long vidmap - .long set_handler - .long sigreturn - -system_call_linkage: - addl $-4, %esp # Push Error Code / Dummy - PUSHALL - pushl %edx - pushl %ecx - pushl %ebx - cmpl $0, %eax # Check bounds for jump table index - jle invalid_call - cmpl $10, %eax - jg invalid_call - call *system_call_jmp(, %eax, 4) - addl $12, %esp # Pop arguments - POPALL - addl $4, %esp # Pop Error Code / Dummy - iret - -invalid_call: - movl $-1, %eax - addl $12, %esp - POPALL - addl $4, %esp - iret - -divide_error_linkage: - .align - #pushl $vector0-256 /* Push inverted vector value onto stack */ - SAVE_ALL /* Save all registers */ - call divide_error /* Call the function handler */ - jmp ret_from_intr /* Jump to pop all registers and return */ - -debug_exception_linkage: - .align - #pushl $vector1-256 - SAVE_ALL - call debug_exception - jmp ret_from_intr - -nmi_interrupt_linkage: - .align - #pushl $vector2-256 - SAVE_ALL - call nmi_interrupt - jmp ret_from_intr - -breakpoint_exception_linkage: - .align - #pushl $vector3-256 - SAVE_ALL - call breakpoint_exception - jmp ret_from_intr - -overflow_exception_linkage: - .align - #pushl $vector4-256 - SAVE_ALL - call overflow_exception - jmp ret_from_intr - -bound_re_linkage: - .align - #pushl $vector5-256 - SAVE_ALL - call bound_re - jmp ret_from_intr - -invalid_opcode_linkage: - .align - #pushl $vector6-256 - SAVE_ALL - call invalid_opcode - jmp ret_from_intr - -device_na_linkage: - .align - #pushl $vector7-256 - SAVE_ALL - call device_na - jmp ret_from_intr - -double_fault_linkage: - .align - #pushl $vector8-256 - SAVE_ALL - call double_fault - jmp ret_from_intr - -coprocessor_so_linkage: - .align - #pushl $vector9-256 - SAVE_ALL - call coprocessor_so - jmp ret_from_intr - -invalid_tss_linkage: - .align - #pushl $vector10-256 - SAVE_ALL - call invalid_tss - jmp ret_from_intr - -segment_np_linkage: - .align - #pushl $vector11-256 - SAVE_ALL - call segment_np - jmp ret_from_intr - -stack_fault_linkage: - .align - #pushl $vector12-256 - SAVE_ALL - call stack_fault - jmp ret_from_intr - -general_protection_linkage: - .align - #pushl $vector13-256 - SAVE_ALL - call general_protection - jmp ret_from_intr - -page_fault_linkage: - .align - #pushl $vector14-256 - SAVE_ALL - call page_fault - jmp ret_from_intr - -reserved_exc_linkage: - iret - -FPUfpe_linkage: - .align - #pushl $vector16-256 - SAVE_ALL - call FPUfpe - jmp ret_from_intr - -alignment_check_linkage: - .align - #pushl $vector17-256 - SAVE_ALL - call alignment_check - jmp ret_from_intr - -machine_check_linkage: - .align - #pushl $vector18-256 - SAVE_ALL - call machine_check - jmp ret_from_intr - -simd_fp_linkage: - .align - # #pushl $vector19-256 - SAVE_ALL - call simd_fp - jmp ret_from_intr - -pit_linkage: - .align - addl $-4, %esp - #pushl $vector33-256 - SAVE_ALL - call pit_interrupt_handler - # addl $4, %esp - jmp ret_from_intr - - - - -keyboard_linkage: - .align - addl $-4, %esp - #pushl $vector33-256 - SAVE_ALL - call handle_keyboard_interrupt - # addl $4, %esp - jmp ret_from_intr - -rtc_interrupt_linkage: - .align - addl $-4, %esp - #pushl $vector40-256 - SAVE_ALL - call rtc_interrupt_handler - jmp ret_from_intr - -ret_from_intr: - addl $4, %esp - popl %ebx /* Pop all saved registers */ - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp - popl %ds - popl %es - popl %fs - addl $4, %esp - iret /* Return from interrupt */ - diff --git a/mp3-LOS/student-distrib/exceptions_linkage.h b/mp3-LOS/student-distrib/exceptions_linkage.h deleted file mode 100644 index 7752d55..0000000 --- a/mp3-LOS/student-distrib/exceptions_linkage.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef EXCEPTIONS_LINKAGE_H -#define EXCEPTIONS_LINKAGE_H - - -/* Exception handlers initialized in idt.c - * Description: Exception handler to be called from assembly linkage - * Inputs: None - * Outputs: None - * Return Value: None - * Side Effects: Prints error onto terminal and program loops */ - -extern void system_call_linkage(void); -extern void divide_error_linkage(void); -extern void debug_exception_linkage(void); -extern void nmi_interrupt_linkage(void); -extern void breakpoint_exception_linkage(void); -extern void overflow_exception_linkage(void); -extern void bound_re_linkage(void); -extern void invalid_opcode_linkage(void); -extern void device_na_linkage(void); -extern void double_fault_linkage(void); -extern void coprocessor_so_linkage(void); -extern void invalid_tss_linkage(void); -extern void segment_np_linkage(void); -extern void stack_fault_linkage(void); -extern void general_protection_linkage(void); -extern void page_fault_linkage(void); -extern void reserved_exc_linkage(void); -extern void FPUfpe_linkage(void); -extern void alignment_check_linkage(void); -extern void machine_check_linkage(void); -extern void simd_fp_linkage(void); -extern void rtc_interrupt_linkage(void); -extern void keyboard_linkage(void); -extern void pit_linkage(void); -#endif diff --git a/mp3-LOS/student-distrib/filesys.c b/mp3-LOS/student-distrib/filesys.c deleted file mode 100644 index afa81d7..0000000 --- a/mp3-LOS/student-distrib/filesys.c +++ /dev/null @@ -1,392 +0,0 @@ -#include "filesys.h" -#include "lib.h" -#include "x86_desc.h" -#include "paging.h" -#include "system_calls.h" - -// global ptrs for initializaition -boot_block_t* boot_block; -dentry_t* dentries; -inode_t* inodes; -data_block_t* data_blocks; - -int dread_index = 0; - - -/* - * filesys_init - * Initialize the file system - * input: uint32_t file_add -- the address of file img - * output: None - * side effect: boot_block, inodes, data_blocks, dentries will be changed - */ -void filesys_init(uint32_t file_add){ - boot_block = (boot_block_t*)file_add; // store boot block - dentries = boot_block->dentries; // store dentries - inodes = (inode_t*)(boot_block + 1); // store inodes - data_blocks = (data_block_t*)(inodes + boot_block->inode_num); // store data blocks -} - - - -/* - * read_dentry_by_index - * Read the content of a dentry with given index - * input: uint8_t index, dentry_t* dentry - * output: -1 for failure and 0 for success - * side effect: dentry can be changed - */ -int32_t read_dentry_by_index (uint8_t index, dentry_t* dentry){ - if(index >= boot_block->dentry_num || index > MAX_FILE_NUM ){ - return -1; - } - dentry_t* dentry_ptr = &(dentries[index]); - dentry->filetype = dentry_ptr->filetype; - dentry->inode_num = dentry_ptr->inode_num; - strncpy((int8_t*)dentry->filename, (int8_t*)dentry_ptr->filename, FNAME_MAX); - return 0; -} - -/* - * read_dentry_by_name - * Read the content of a dentry with given name - * input: const uint8_t* fname, dentry_t* dentry - * output: -1 for failure and 0 for success - * side effect: dentry can be changed - */ -int32_t read_dentry_by_name(const uint8_t* fname, dentry_t* dentry){ - uint8_t i; - dentry_t* current_dentry; - if (fname == NULL) - return -1; - if (strlen((int8_t*)fname) > 32) - return -1; - for(i=0; identry_num; i++){ - current_dentry = &(dentries[i]); - // puts((int8_t*)current_dentry->filename); - // printf(" i = %d, fname: %s, dentry_filename: %s\n", i, fname, current_dentry->filename); - if(strncmp((int8_t*)fname, (int8_t*)current_dentry->filename, FNAME_MAX)==0){ - /* The file name is the same, use read_index to assign value */ - // printf("\n index in dentries: %d\n", i); - read_dentry_by_index(i, dentry); - - return 0; - } - } - return -1; - -} -/* - * read_file_by_name - * Read the content of a file with given name - * Input: const uint8_t* fname, uint8_t* buf, uint32_t* length - * Output: -1 for failure and 0 for success - * Side effect: buf can be changed - */ -int32_t read_file_by_name(const uint8_t* fname, uint8_t* buf, uint32_t* length){ - dentry_t dentry; - uint8_t index = 0; - printf("file_name: "); - printf((int8_t*) fname); - read_dentry_by_name(fname, &dentry); - index = dentry.inode_num; - printf(" index:%d\n",index); - return read_data(index, 0, buf, length); -} - -/* - * read_data - * Read the content of a dentry with given index - * Input:uint32_t inode_index, uint32_t offset, uint8_t* buf, uint32_t* length - * Output: bytes of data we have successfully read - * Side effect: buf can be changed - */ -int32_t read_data(uint32_t inode_index, uint32_t offset, uint8_t* buf, uint32_t* length){ - //int k; - uint32_t i,j; - inode_t* inode; - // data_block_t* cur_datablock; // Pointer to current data block - uint32_t cur_db_index; // index of current data block - uint32_t buf_count; - - - // uint32_t first_block; // Which data block we should start to read - // uint32_t first_offset; // Which position in the start block we should start to read - // uint32_t last_block; // Which data block we should end reading - // uint32_t last_offset; // Which position in the last block we should end reading - - if(offset >= inodes[inode_index].len) return 0; - if(inode_index > (boot_block->inode_num-1)) return 0; - - //printf("length: %d, inode_len: %d\n", *length, inodes[inode_index].len); - if (*length + offset > inodes[inode_index].len) *length = inodes[inode_index].len - offset; - // for (k = 0; k < 64; k++) { - // printf("i: %d, len: %d; ",k,inodes[k].len); - // if (k %4 == 0) printf("\n"); - // } - if (*length <= 0) return 0; - //printf("length: %d\n", *length); - inode = &(inodes[inode_index]); - // buf_count = 0; - - /* Calculate how many data blocks are used and start/end positions */ - // first_block = offset / BLOCK_SIZE; - // first_offset = offset % BLOCK_SIZE; - // last_block = (*length - 1 + offset) / BLOCK_SIZE; - // last_offset = (*length - 1 + offset) % BLOCK_SIZE; - - - i = offset / BLOCK_SIZE; - j = offset % BLOCK_SIZE; - for (buf_count = 0; buf_count < *length; buf_count++, j++, buf++) { - if(j >= BLOCK_SIZE){ - j = 0; - i++; - } - cur_db_index = (inodes[inode_index].data_block)[i]; - if(cur_db_index >= boot_block->data_blocks_num){ - return buf_count; - } - // cur_datablock = &(data_blocks[cur_db_index]); - // memcpy(buf, &(cur_datablock->data[j]), 1); - *buf = data_blocks[cur_db_index].data[j]; - } - - - - - // printf("first_block:%d, first_offset:%d\n",first_block,first_offset); - // printf("last_block: %d, last_offset:%d\n",last_block,last_offset); - - // for(i=first_block; i<=last_block; i++){ - // cur_db_index = (inodes[inode_index].data_block)[i]; - // // printf("cur_db_index: %d\n",cur_db_index); - // cur_datablock = &(data_blocks[cur_db_index]); - - // if(i == first_block){ - // //printf("copy to buf...\n"); - // if(first_block==last_block){ - // memcpy(buf, &(cur_datablock->data[first_offset]), *length); - // buf += *length; - // buf_count += *length; - // // for (j = first_offset; j < (*length - 1 + offset); j++) { - // // memcpy(buf, &(cur_datablock->data[j]), 1); - // // buf++; - // // buf_count++; - // // } - // // printf("last data block reached\n"); - // } - // else{ - // memcpy(buf, &(cur_datablock->data[first_offset]), BLOCK_SIZE-first_offset); - // buf += BLOCK_SIZE - first_offset; - // buf_count += BLOCK_SIZE - first_offset; - // } - // continue; - // } - // if(i == last_block){ - // memcpy(buf, cur_datablock->data, last_offset + 1); - // buf += last_offset + 1; - // buf_count += last_offset + 1; - // // printf("last data block reached\n"); - // break; - // } - // memcpy(buf, cur_datablock->data, BLOCK_SIZE); // buf all block - // buf += BLOCK_SIZE; - // buf_count += BLOCK_SIZE; - // } - - - // if(i == first_block){ - // //printf("copy to buf...\n"); - // for (j = first_offset; j < 4095; j++) { - // *buf = (cur_datablock->data[j]); - // buf++; - // buf_count++; - // } - // continue; - // } - // if(i == last_block){ - // for (j = 0; j < last_offset; j++) { - // *buf = (cur_datablock->data[j]); - // buf++; - // buf_count++; - // } - // // printf("last data block reached\n"); - // break; - // } - // for (j = 0; j < 4095; j++) { - // *buf = (cur_datablock->data[j]); - // buf++; - // buf_count++; - // } - // } - - return buf_count; -} - - -/* - * read_directory - * read a directory - * Inputs: uint8_t* buf, int index, uint32_t *ftype, uint32_t *fsize - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can read a directory by index - */ -int32_t read_directory(uint8_t* buf, int index, uint32_t *ftype, uint32_t *fsize){ - - int i = 0; // for index to store at most 32 length file name - uint32_t fname_len; // length for filename to buf - dentry_t dentry; // temp dir entry - dentry = dentries[index]; - if (index >= boot_block->dentry_num) // if index out of range - return -1; - memset(buf, 32, FNAME_MAX); // initialize to spaces - - - fname_len = strlen((int8_t*)dentry.filename); - if (fname_len > FNAME_MAX) fname_len = FNAME_MAX; // control length less than or equal 32 - read_dentry_by_name((uint8_t*)&(dentry.filename), &dentry); - for (i = 0; i <= fname_len; i++) { - memset(buf + i, dentry.filename[i], 1); // copy first 32 bytes to buf - } - *ftype = dentry.filetype; - *fsize = inodes[dentry.inode_num].len; - - return fname_len; -} - - -/* - * fopen - * Open a file with its filename - * Inputs: fname - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can open the file - */ -int32_t fopen(const uint8_t* fname){ - dentry_t dentry; - if (read_dentry_by_name(fname, &dentry)) - return -1; - else - return 0; -} - -/* - * fread - * Open a file with its filename - * Inputs: fname - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can open the file - */ -int32_t fread(int32_t fd, void* buf, int32_t n_bytes) { - if (n_bytes < 0 || buf == NULL || fd < 0 || fd > MAX_FILE_NUM) { - printf("fread fail...\n"); - return -1; - } - - uint32_t length = n_bytes; - register int32_t esp_value asm("esp"); - uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - uint32_t inode_num = cur_pcb->file_descs[fd].inode; - uint32_t offset = cur_pcb->file_descs[fd].file_pos; - //printf("inode_num = %d, offset = %d, buf = %s, length = %d\n",inode_num, offset, buf, length); - return read_data(inode_num, offset, buf, &length); -} - -/* - * fclose - * Open a file with its filename - * Inputs: fname - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can open the file - */ -int32_t fclose(int32_t fd){ - return 0; -} - -/* - * fwrite - * Open a file with its filename - * Inputs: fname - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can open the file - */ -int32_t fwrite(int32_t fd, const void* buf, int32_t n_bytes){ - return 0; -} - -/* - * dopen - * Open a file with its filename - * Inputs: fname - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can open the file - */ -int32_t dopen(const uint8_t* filename){ - return 0; -} - -/* - * dread - * Open a file with its filename - * Inputs: fname - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can open the file - */ -int32_t dread(int32_t fd, void* buf, int32_t n_bytes){ - if (n_bytes < 0 || buf == NULL || fd < 0 || fd > MAX_FILE_NUM) { - printf("dread fail...\n"); - return -1; - } - int32_t length = 0; - // register int32_t esp_value asm("esp"); - // uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - // pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - // uint32_t inode_num = cur_pcb->file_descs[fd].inode; - // uint32_t offset = cur_pcb->file_descs[fd].file_pos; - uint32_t ftype; - uint32_t fsize; - length = read_directory(buf, dread_index, &ftype, &fsize); - // printf("fd = %d, buf = %s, n_bytes = %d\n",fd, buf, n_bytes); - // printf("%s\n",buf); - if (length == -1){ - dread_index = 0; - return 0; - } else { - dread_index++; - } - return length; -} - -/* - * dwrite - * Open a file with its filename - * Inputs: fname - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can open the file - */ -int32_t dwrite(int32_t fd, const void* buf, int32_t n_bytes){ - return 0; -} - -/* - * dclose - * Open a file with its filename - * Inputs: fname - * Output: 0 if success -1 if fail - * Side Effect: None - * Coverage: Check whether we can open the file - */ -int32_t dclose(int32_t fd){ - return 0; -} - diff --git a/mp3-LOS/student-distrib/filesys.h b/mp3-LOS/student-distrib/filesys.h deleted file mode 100644 index f3ae5ae..0000000 --- a/mp3-LOS/student-distrib/filesys.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef FILESYS_H -#define FILESYS_H - -#include "types.h" - -#define BLOCK_SIZE 4096 // Each block is 4096 bytes -#define MAX_FILE_NUM 63 // Boot block can hold 64 entries including statistic part at most. So the biggest index is 63 -#define FNAME_MAX 32 // Longest file name is 32 bytes -#define SIZE_4B 4 -#define MAX_FILE_SIZE 4*36200 -typedef struct dentry_t { - uint8_t filename[FNAME_MAX]; - uint32_t filetype; - uint32_t inode_num; - uint32_t reserved[6]; // 24bytes reserved, 24/4 = 6 -} dentry_t; - -typedef struct inode_t { - uint32_t len; // 4 bytes - uint32_t data_block[(BLOCK_SIZE - SIZE_4B) / SIZE_4B]; -} inode_t; - -typedef struct boot_block_t { - uint32_t dentry_num; - uint32_t inode_num; - uint32_t data_blocks_num; - uint32_t reserved[13]; // 52bytes reserved, 52/4 = 13 - dentry_t dentries[MAX_FILE_NUM]; -} boot_block_t; - -typedef struct data_block_t { - uint8_t data[BLOCK_SIZE]; -} data_block_t; - - -/*initilize filesystem*/ -void filesys_init(uint32_t file_add); - -/*The three routines provided by the file system module return -1 on failure, indicating a non-existent file or invalid -index in the case of the first two calls, or an invalid inode number in the case of the last routine. Note that the directory -entries are indexed starting with 0. Also note that the read data call can only check that the given inode is within the -valid range. It does not check that the inode actually corresponds to a file (not all inodes are used). However, if a bad -data block number is found within the file bounds of the given inode, the function should also return -1*/ - -int32_t read_dentry_by_name(const uint8_t* fname, dentry_t* dentry); -int32_t read_dentry_by_index (uint8_t index, dentry_t* dentry); -int32_t read_data(uint32_t inode_index, uint32_t offset, uint8_t* buf, uint32_t* length); - - -int32_t read_file_by_name(const uint8_t* fname, uint8_t* buf, uint32_t* length); -int32_t read_directory(uint8_t* buf, int index, uint32_t* ftype, uint32_t* fsize); - - -/*for file*/ -int32_t fopen(const uint8_t* fname); -int32_t fclose(int32_t fd); -int32_t fread(int32_t fd, void* buf, int32_t nbytes); -int32_t fwrite(int32_t fd, const void* buf, int32_t nbytes); -/*for dir*/ -int32_t dopen(const uint8_t* fname); -int32_t dclose(int32_t fd); -int32_t dread(int32_t fd, void* buf, int32_t n_bytes); -int32_t dwrite(int32_t fd, const void* buf, int32_t nbytes); - -#endif diff --git a/mp3-LOS/student-distrib/filesys_img b/mp3-LOS/student-distrib/filesys_img deleted file mode 100644 index ea4bd7a..0000000 Binary files a/mp3-LOS/student-distrib/filesys_img and /dev/null differ diff --git a/mp3-LOS/student-distrib/gitignore b/mp3-LOS/student-distrib/gitignore deleted file mode 100644 index 5fdb580..0000000 --- a/mp3-LOS/student-distrib/gitignore +++ /dev/null @@ -1,116 +0,0 @@ -# ECE 391 gitignore -# Author: Lavin Devnani (devnani2) -# -# Permission to use, copy, modify, and distribute this software and its -# documentation for any purpose, without fee, and without written agreement is -# hereby granted, provided that the above copyright notice and the following -# two paragraphs appear in all copies of this software. -# -# IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF ILLINOIS BE LIABLE TO -# ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL -# DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -# EVEN IF THE AUTHOR AND/OR THE UNIVERSITY OF ILLINOIS HAS BEEN ADVISED -# OF THE POSSIBILITY OF SUCH DAMAGE. -# -# THE AUTHOR AND THE UNIVERSITY OF ILLINOIS SPECIFICALLY DISCLAIM ANY -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE -# PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND NEITHER THE AUTHOR NOR -# THE UNIVERSITY OF ILLINOIS HAS ANY OBLIGATION TO PROVIDE MAINTENANCE, -# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." -# - -# C - https://github.com/github/gitignore/blob/master/C.gitignore -# Prerequisites -*.d -*.DS_Store - -# Object files -*.o -*.ko -*.elf - -# Linker output -*.ilk -*.map -*.exp - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ -*.su -*.idb -*.pdb - -# Kernel Module Compile Results -*.mod* -*.cmd -.tmp_versions/ -modules.order -Module.symvers -Mkfile.old -dkms.conf - -# C++ - https://github.com/github/gitignore/blob/master/C%2B%2B.gitignore -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - - -# 391 specific -*.qcow -source/ -bootimg - diff --git a/mp3-LOS/student-distrib/i8259.c b/mp3-LOS/student-distrib/i8259.c deleted file mode 100644 index 783ff32..0000000 --- a/mp3-LOS/student-distrib/i8259.c +++ /dev/null @@ -1,96 +0,0 @@ -/* i8259.c - Functions to interact with the 8259 interrupt controller - * vim:ts=4 noexpandtab - */ - -#include "i8259.h" -#include "lib.h" - -/* Interrupt masks to determine which interrupts are enabled and disabled */ -uint8_t master_mask; /* IRQs 0-7 */ -uint8_t slave_mask; /* IRQs 8-15 */ - -/* - * i8259_init(void) - * Initialize the 8259 PIC - * Inputs: void - * Outputs: none - */ -void i8259_init(void) { - master_mask = MASK_INIT; - slave_mask = MASK_INIT; - - /* mask all of 8259A-1 and 8259A-2 */ - outb(MASK_INIT, MASTER_8259_WRITE_PORT); - outb(MASK_INIT, SLAVE_8259_WRITE_PORT); - - /* Any command with A = 0 (writing to 0x20) and D4 = 1 is recognized as ICW1.*/ - outb(ICW1, MASTER_8259_PORT); // ICW1: select 8259A-1 master init - outb(ICW2_MASTER, MASTER_8259_WRITE_PORT); // ICW2: 8259A-1 IR0-7 mapped to 0x20 - 0x27 - outb(ICW3_MASTER, MASTER_8259_WRITE_PORT); // ICW3: 8259A-1(master) has a slave on IR2 - outb(ICW4, MASTER_8259_WRITE_PORT); // ICW4: master expects normal EOI - - outb(ICW1, SLAVE_8259_PORT); // ICW1: select 8259A-2 slave init - outb(ICW2_SLAVE, SLAVE_8259_WRITE_PORT); // ICW2: 8259A-2 IR0-7 mapped to 0x28 - 0x2f - outb(ICW3_SLAVE, SLAVE_8259_WRITE_PORT); // ICW3: 8259A-2 is a slave on master's IR2 - outb(ICW4, SLAVE_8259_WRITE_PORT); // ICW4: slave expects normal EOI - - enable_irq(2); // enable IR2 for slave -} - -/* - * enable_irq(uint32_t irq_num) - * Enable (unmask) the specified IRQ, 0 to indicate unmask - * Inputs: irq_num - * Outputs: none - */ -void enable_irq(uint32_t irq_num) { - if (irq_num > MAX_IRQ) return; // out of range - if (irq_num <= MAX_MASTER_IRQ) { // master - master_mask &= (~(1 << irq_num)); - outb(master_mask, MASTER_8259_WRITE_PORT); - return; - } - slave_mask &= (~(1 << (irq_num - MAX_MASTER_IRQ - 1))); // slave - outb(slave_mask, SLAVE_8259_WRITE_PORT); - return; -} - -/* - * disable_irq(uint32_t irq_num) - * disable (mask) the specified IRQ, 1 to indicate mask - * Inputs: irq_num - * Outputs: none - */ -void disable_irq(uint32_t irq_num) { - if (irq_num > MAX_IRQ) return; // out of range - if (irq_num <= MAX_MASTER_IRQ) { // master - master_mask |= (~(1 << irq_num)); - outb(master_mask, MASTER_8259_WRITE_PORT); - return; - } - slave_mask |= (~(1 << (irq_num - MAX_MASTER_IRQ - 1))); // slave - outb(slave_mask, SLAVE_8259_WRITE_PORT); - return; -} - -/* - * send_eoi(uint32_t irq_num) - * Send end-of-interrupt signal for the specified IRQ - * Inputs: irq_num - * Outputs: none - */ -void send_eoi(uint32_t irq_num) { - /* End-of-interrupt byte. This gets OR'd with - * the interrupt number and sent out to the PIC - * to declare the interrupt finished */ - - if (irq_num > MAX_IRQ) return; // out of range - if (irq_num <= MAX_MASTER_IRQ) { // master - outb(EOI | (irq_num), MASTER_8259_PORT); - return; - } - // slave - outb(EOI | (irq_num - MAX_MASTER_IRQ), SLAVE_8259_PORT); - outb(EOI | 2, MASTER_8259_PORT); // also send to master IR2 - return; -} diff --git a/mp3-LOS/student-distrib/i8259.h b/mp3-LOS/student-distrib/i8259.h deleted file mode 100644 index cefbae2..0000000 --- a/mp3-LOS/student-distrib/i8259.h +++ /dev/null @@ -1,48 +0,0 @@ -/* i8259.h - Defines used in interactions with the 8259 interrupt - * controller - * vim:ts=4 noexpandtab - */ - -#ifndef _I8259_H -#define _I8259_H - -#include "types.h" - -/* Ports that each PIC sits on */ -#define MASTER_8259_PORT 0x20 -#define SLAVE_8259_PORT 0xA0 -#define MASTER_8259_WRITE_PORT 0x21 -#define SLAVE_8259_WRITE_PORT 0xA1 - -/* Initialization control words to init each PIC. - * See the Intel manuals for details on the meaning - * of each word */ -#define ICW1 0x11 -#define ICW2_MASTER 0x20 -#define ICW2_SLAVE 0x28 -#define ICW3_MASTER 0x04 -#define ICW3_SLAVE 0x02 -#define ICW4 0x01 - - -#define MASK_INIT 0xFF -#define MAX_IRQ 15 // 8 - 15 -#define MAX_MASTER_IRQ 7 // 0 - 7 - -/* End-of-interrupt byte. This gets OR'd with - * the interrupt number and sent out to the PIC - * to declare the interrupt finished */ -#define EOI 0x20 - -/* Externally-visible functions */ - -/* Initialize both PICs */ -void i8259_init(void); -/* Enable (unmask) the specified IRQ */ -void enable_irq(uint32_t irq_num); -/* Disable (mask) the specified IRQ */ -void disable_irq(uint32_t irq_num); -/* Send end-of-interrupt signal for the specified IRQ */ -void send_eoi(uint32_t irq_num); - -#endif /* _I8259_H */ diff --git a/mp3-LOS/student-distrib/idt.c b/mp3-LOS/student-distrib/idt.c deleted file mode 100644 index 41e9afa..0000000 --- a/mp3-LOS/student-distrib/idt.c +++ /dev/null @@ -1,177 +0,0 @@ -#include "idt.h" -#include "lib.h" -#include "x86_desc.h" -#include "exceptions_linkage.h" -#include "rtc.h" -#include "system_calls.h" - - -/* Exception handlers - * Description: Exception handler to be called from assembly linkage - * Inputs: None - * Outputs: None - * Return Value: None - * Side Effects: Prints error onto terminal and program loops */ -void divide_error(){ - printf("Divide Error Exception\n"); - while(1); -} - -void debug_exception(){ - printf("Debug Exception\n"); - while(1); -} - -void nmi_interrupt(){ - printf("NMI Interrupt\n"); - while(1); -} - -void breakpoint_exception(){ - printf("Breakpoint Exception\n"); - while(1); -} - -void overflow_exception(){ - printf("Overflow Exception\n"); - while(1); -} - -void bound_re(){ - printf("BOUND Range Exceeded Exception\n"); - while(1); -} - -void invalid_opcode(){ - printf("Invalid Opcode Exception\n"); - while(1); -} - -void device_na(){ - printf("Device Not Available Exception\n"); - while(1); -} - -void double_fault(){ - printf("Double Fault Exception\n"); - while(1); -} - -void coprocessor_so(){ - printf("Coprocessor Segment Overun\n"); - while(1); -} - -void invalid_tss(){ - printf("Invalid TSS Exception\n"); - while(1); -} - -void segment_np(){ - printf("Segment Not Present\n"); - while(1); -} - -void stack_fault(){ - printf("Stack Fault Exception\n"); - while(1); -} - -void general_protection(){ - printf("General Protection Exception\n"); - while(1); -} - -void page_fault(){ - printf("Page-Fault Exception\n"); - while(1); -} - -// void reserved_exc(){ -// printf("EXCEPTION Reserved\n"); -// while(1); -// } - -void FPUfpe(){ - printf("x87 FPU Floating Point Error\n"); - while(1); -} - -void alignment_check(){ - printf("Alignment Check Exception\n"); - while(1); -} - -void machine_check(){ - printf("Machine-Check Exception\n"); - while(1); -} - -void simd_fp(){ - printf("SIMD Floating-Point Exception\n"); - while(1); -} - -/* idt_init - * Description: Initialize the 256 entries of the IDT and link them to the assembly linkage. - Save idt address onto idtr after init is complete. - * Inputs: None - * Outputs: None - * Return Value: None - * Side Effects: Changes IDT memory */ -void idt_init() { - int i; - - /* Loop through all 256 vectors in idt and initialize with default values */ - for(i=0; iflags); - - /* Are mem_* valid? */ - if (CHECK_FLAG(mbi->flags, 0)) - printf("mem_lower = %uKB, mem_upper = %uKB\n", (unsigned)mbi->mem_lower, (unsigned)mbi->mem_upper); - - /* Is boot_device valid? */ - if (CHECK_FLAG(mbi->flags, 1)) - printf("boot_device = 0x%#x\n", (unsigned)mbi->boot_device); - - /* Is the command line passed? */ - if (CHECK_FLAG(mbi->flags, 2)) - printf("cmdline = %s\n", (char *)mbi->cmdline); - - if (CHECK_FLAG(mbi->flags, 3)) { - int mod_count = 0; - int i; - module_t* mod = (module_t*)mbi->mods_addr; - while (mod_count < mbi->mods_count) { - printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start); - printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end); - printf("First few bytes of module:\n"); - for (i = 0; i < 16; i++) { - printf("0x%x ", *((char*)(mod->mod_start+i))); - } - printf("\n"); - fs_addr = mod->mod_start; // get file system address - mod_count++; - mod++; - } - } - /* Bits 4 and 5 are mutually exclusive! */ - if (CHECK_FLAG(mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)) { - printf("Both bits 4 and 5 are set.\n"); - return; - } - - /* Is the section header table of ELF valid? */ - if (CHECK_FLAG(mbi->flags, 5)) { - elf_section_header_table_t *elf_sec = &(mbi->elf_sec); - printf("elf_sec: num = %u, size = 0x%#x, addr = 0x%#x, shndx = 0x%#x\n", - (unsigned)elf_sec->num, (unsigned)elf_sec->size, - (unsigned)elf_sec->addr, (unsigned)elf_sec->shndx); - } - - /* Are mmap_* valid? */ - if (CHECK_FLAG(mbi->flags, 6)) { - memory_map_t *mmap; - printf("mmap_addr = 0x%#x, mmap_length = 0x%x\n", - (unsigned)mbi->mmap_addr, (unsigned)mbi->mmap_length); - for (mmap = (memory_map_t *)mbi->mmap_addr; - (unsigned long)mmap < mbi->mmap_addr + mbi->mmap_length; - mmap = (memory_map_t *)((unsigned long)mmap + mmap->size + sizeof (mmap->size))) - printf(" size = 0x%x, base_addr = 0x%#x%#x\n type = 0x%x, length = 0x%#x%#x\n", - (unsigned)mmap->size, - (unsigned)mmap->base_addr_high, - (unsigned)mmap->base_addr_low, - (unsigned)mmap->type, - (unsigned)mmap->length_high, - (unsigned)mmap->length_low); - } - - /* Construct an LDT entry in the GDT */ - { - seg_desc_t the_ldt_desc; - the_ldt_desc.granularity = 0x0; - the_ldt_desc.opsize = 0x1; - the_ldt_desc.reserved = 0x0; - the_ldt_desc.avail = 0x0; - the_ldt_desc.present = 0x1; - the_ldt_desc.dpl = 0x0; - the_ldt_desc.sys = 0x0; - the_ldt_desc.type = 0x2; - - SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size); - ldt_desc_ptr = the_ldt_desc; - lldt(KERNEL_LDT); - } - - /* Construct a TSS entry in the GDT */ - { - seg_desc_t the_tss_desc; - the_tss_desc.granularity = 0x0; - the_tss_desc.opsize = 0x0; - the_tss_desc.reserved = 0x0; - the_tss_desc.avail = 0x0; - the_tss_desc.seg_lim_19_16 = TSS_SIZE & 0x000F0000; - the_tss_desc.present = 0x1; - the_tss_desc.dpl = 0x0; - the_tss_desc.sys = 0x0; - the_tss_desc.type = 0x9; - the_tss_desc.seg_lim_15_00 = TSS_SIZE & 0x0000FFFF; - - SET_TSS_PARAMS(the_tss_desc, &tss, tss_size); - - tss_desc_ptr = the_tss_desc; - - tss.ldt_segment_selector = KERNEL_LDT; - tss.ss0 = KERNEL_DS; - tss.esp0 = 0x800000; - ltr(KERNEL_TSS); - } - filesys_init(fs_addr); - idt_init(); - /* Init the PIC */ - i8259_init(); - paging_init(); - rtc_init(); - key_init(); - terminal_init(); - pid_init(); - // Checkpoint 5 - pit_init(); - scheduler_init(); - /* Initialize devices, memory, filesystem, enable device interrupts on the - * PIC, any other initialization stuff... */ - - /* Enable interrupts */ - /* Do not enable the following until after you have set up your - * IDT correctly otherwise QEMU will triple fault and simple close - * without showing you any output */ - clear(); - printf("Enabling Interrupts\n"); - sti(); - -#ifdef RUN_TESTS - /* Run tests */ - // launch_tests(); - - -#endif - clear(); - /* Execute the first program ("shell") ... */ - // printf("====== TERMINAL %d ======\n", curr_tid); - execute((uint8_t*)"shell"); - // clear(); - /* Spin (nicely, so we don't chew up cycles) */ - asm volatile (".1: hlt; jmp .1;"); -} diff --git a/mp3-LOS/student-distrib/keyboard.c b/mp3-LOS/student-distrib/keyboard.c deleted file mode 100644 index e478b90..0000000 --- a/mp3-LOS/student-distrib/keyboard.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "keyboard.h" -#include "lib.h" -#include "i8259.h" -#include "terminal_driver.h" -#include "rtc.h" - -int SHIFTED; -int CAPS_LOCK; -int CONTROL; -int capslock_flag = 0; -int ctrl_flag = 0; -int shift_flag = 0; -int alt_flag = 0; -int numlock_flag = 0; - -char ASCII[][2] = { - {0,0}, - {ASCII_ESC,ASCII_ESC}, - {'1','!'}, - {'2','@'}, - {'3','#'}, - {'4','$'}, - {'5','%'}, - {'6','^'}, - {'7','&'}, - {'8','*'}, - {'9','('}, - {'0',')'}, - {'-','_'}, - {'=','+'}, - {ASCII_BACKSPACE,ASCII_BACKSPACE}, - {ASCII_TAB, ASCII_TAB}, - {'q','Q'}, - {'w','W'}, - {'e','E'}, - {'r','R'}, - {'t','T'}, - {'y','Y'}, - {'u','U'}, - {'i','I'}, - {'o','O'}, - {'p','P'}, - {'[','{'}, - {']','}'}, - {ASCII_ENTER, ASCII_ENTER}, - {0,0}, //LCTRL - {'a','A'}, - {'s','S'}, - {'d','D'}, - {'f','F'}, - {'g','G'}, - {'h','H'}, - {'j','J'}, - {'k','K'}, - {'l','L'}, - {';',':'}, - {ASCII_SINGLE_QUOTE,'"'}, - {0,0}, //TODO: BACKTICK - {0,0}, //lshift - {ASCII_BACKSLASH,ASCII_VERTICAL_BAR}, - {'z','Z'}, - {'x','X'}, - {'c','C'}, - {'v','V'}, - {'b','B'}, - {'n','N'}, - {'m','N'}, - {',','<'}, - {'.','>'}, - {'/','?'}, - {'z','Z'}, - {'x','X'}, - {'c','C'}, - {' ',' '}, - {'b','B'}, - {'n','N'}, - {'m','M'}, - {',','<'}, - {'.','>'}, - {'/','?'}, - {0,0}, //rshift - {'*','*'}, - {0,0}, //LALT - {' ', ' '}, - {0,0}, //CAPS LOCK - {0,0}, //f1 - {0,0}, //f2 - {0,0}, //f3 - {0,0}, //f4 - {0,0}, //f5 - {0,0}, //f6 - {0,0}, //f6 - {0,0}, //f7 - {0,0}, //f8 - {0,0}, //f9 - {0,0}, //f10 - {0,0}, //NUMLOCK - {0,0}, //SCROLL LOCK - {'7','7'}, //KEYPAD START - {'8','8'}, - {'9','9'}, - {'-','-'}, - {'4','4'}, - {'5','5'}, - {'6','6'}, - {'+','+'}, - {'1','1'}, - {'2','2'}, - {'3','3'}, - {'0','0'}, - {'0','0'}, //KEYPAD END - {0,0}, //0x54 - {0,0}, //0x55 - {0,0}, //0x56 - {0,0}, //0x57 - {0,0}, - - }; - -void handle_keyboard_interrupt(void) { -// //Local Variables - int released; - int alt_char; - char chara; - uint8_t input; - send_eoi(KBD_IRQ_NUM); - - - cli(); - // disable_irq(RTC_IRQ_NUM); - //clear(); - // printf("Keyboard Interrupt Called!\n"); //Debug - - // //Set Default Values - // released = false; - - // //READ PORT 0x60 - input = inb(KEYBOARD_PORT); - // printf("SCANCODE: %x\n", input); //Debug - - //Determine if is being released - released = 0; - if (input > 0x80) { - input -= 0x80; - released = 1; - //printf("Key Released!\n"); //Debug - } - switch (input) { - case CAPS_LOCK_PRESSED: - capslock_flag = !capslock_flag; - break; - case NUM_LOCK_PRESSED: - numlock_flag = !numlock_flag; - break; - case LSHIFT_PRESSED: - shift_flag = 1; - break; - case RALT_PRESSED: - shift_flag = 1; - break; - case LSHIFT_RELEASED: - shift_flag = 0; - break; - case RALT_RELEASED: - shift_flag = 0; - break; - case RSHIFT_PRESSED: - ctrl_flag = 1; - break; - case RSHIFT_RELEASED: - ctrl_flag = 0; - break; - case LALT_PRESSED: - alt_flag = 1; - // printf("ALT PRESS\n"); - break; - case LALT_RELEASED: - alt_flag = 0; - // printf("ALT RELEASE\n"); - break; - - - case F1_PRESSED: - // printf("F1 PRESS\n"); - // printf("alt_press: %d\n",alt_press); - if(alt_flag) { - terminal_switch(0); - } - break; - case F2_PRESSED: - // printf("F2 PRESS\n"); - if(alt_flag) - terminal_switch(1); - break; - case F3_PRESSED: - // printf("F3 PRESS\n"); - if(alt_flag) - terminal_switch(2); - break; - default: - //Process Inputs Without ASCII VALUES - if (ASCII[input][0] == 0) { - switch(input) { - //case SCANCODE_CAPS_LOCK: if (!released) CAPS_LOCK = (!CAPS_LOCK); - case SCANCODE_LSHIFT: - SHIFTED = released ^ 1; - case SCANCODE_RSHIFT: - SHIFTED = !released; - case (SCANCODE_LCONTROL) : - CONTROL = (released ^ 1); - printf("PRESS LCTL"); - break; - default: // printf("Key Not Implemented! Scancode: %x\n", input); - printf(""); - } - send_eoi(KBD_IRQ_NUM); - sti(); - // enable_irq(RTC_IRQ_NUM); - return; - } - - - // //Determine if we are using the shifted character based on whether or not its a letter - // else if (ASCII[input][0] >= ASCII_a && ASCII[input][0] <= ASCII_z) alt_char = CAPS_LOCK ^ SHIFTED; - // else alt_char = SHIFTED; - - //Determine if we are using the alternative character - alt_char = SHIFTED; - if (ASCII[input][0] >= ASCII_a && ASCII[input][0] <= ASCII_z) alt_char ^= CAPS_LOCK; - - //Determine Character of the Scancode from table - chara = ASCII[input][alt_char]; - - //Clear Command - if (ctrl_flag && chara == 'l') { - clear(); - key_buffer_clear(); - } - - //Print the Character and send to buffer; - if (released == 0 && CONTROL == 0) { - // if (of_flag == 0 || chara == ASCII_ENTER) putc(chara); - key_buffer_push(chara); - } - break; - } - - - - send_eoi(KBD_IRQ_NUM); - // outb(0x22, 0x20); - sti(); - // enable_irq(RTC_IRQ_NUM); -} - -void key_init(void) { // https://wiki.osdev.org/Keyboard - printf("Running key_init...\n"); - enable_irq(KBD_IRQ_NUM); - CAPS_LOCK = 0; - SHIFTED = 0; - CONTROL = 0; -} diff --git a/mp3-LOS/student-distrib/keyboard.h b/mp3-LOS/student-distrib/keyboard.h deleted file mode 100644 index 4d26713..0000000 --- a/mp3-LOS/student-distrib/keyboard.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _KEYBOARD_H -#define _KEYBOARD_H - -#include "types.h" - -#define KBD_IRQ_NUM 1 // use IR1 of master - -#define KEYBOARD_PORT 0x60 -#define NUM_SCANCODES 0x58 - -#define ASCII_ESC 27 -#define ASCII_TAB 9 -#define ASCII_BACKSLASH 92 -#define ASCII_VERTICAL_BAR 124 -#define ASCII_CAPS_LOCK 20 -#define ASCII_ENTER 10 -#define ASCII_SINGLE_QUOTE 39 -#define ASCII_SPACE 32 -#define ASCII_BACKSPACE 8 -#define ASCII_a 97 -#define ASCII_z 122 - - -#define SCANCODE_CAPS_LOCK 0x0E -#define SCANCODE_LSHIFT 0x2A -#define SCANCODE_RSHIFT 0x38 -#define SCANCODE_LCONTROL 0x1D - -#define CAPS_LOCK_PRESSED 0x3A - -#define LSHIFT_PRESSED 0x2A -#define LSHIFT_RELEASED 0xAA - -#define RSHIFT_PRESSED 0x1D -#define RSHIFT_RELEASED 0x9D - -#define LALT_PRESSED 0x38 -#define LALT_RELEASED 0xB8 - -#define RALT_PRESSED 0x36 -#define RALT_RELEASED 0xB6 - -#define NUM_LOCK_PRESSED 0x45 - -#define F1_PRESSED 0x3B -#define F2_PRESSED 0x3C -#define F3_PRESSED 0x3D -#define F4_PRESSED 0x3E -#define F5_PRESSED 0x3F -#define F6_PRESSED 0x40 -#define F7_PRESSED 0x41 -#define F8_PRESSED 0x42 -#define F9_PRESSED 0x43 -#define F10_PRESSED 0x44 -#define F11_PRESSED 0x57 -#define F12_PRESSED 0x58 -// Reference: https://kbdlayout.info/kbdusx/scancodes - -// initialize keyboard - -extern void key_init(void); - -extern void handle_keyboard_interrupt(void); - -#endif diff --git a/mp3-LOS/student-distrib/lib.c b/mp3-LOS/student-distrib/lib.c deleted file mode 100644 index abd2c19..0000000 --- a/mp3-LOS/student-distrib/lib.c +++ /dev/null @@ -1,776 +0,0 @@ -/* lib.c - Some basic library functions (printf, strlen, etc.) - * vim:ts=4 noexpandtab */ - -#include "lib.h" -#include "keyboard.h" -#include "terminal_driver.h" - -#define VIDEO 0xB8000 -#define NUM_COLS 80 -#define NUM_ROWS 25 -#define ATTRIB 0x7 - -static int screen_x; -static int screen_y; -static char* video_mem = (char *)VIDEO; - -/* void clear(void); - * Inputs: void - * Return Value: none - * Function: Clears video memory */ -void clear(void) { - int32_t i; - for (i = 0; i < NUM_ROWS * NUM_COLS; i++) { - *(uint8_t *)(video_mem + (i << 1)) = ' '; - *(uint8_t *)(video_mem + (i << 1) + 1) = ATTRIB; - } - screen_x = 0; - screen_y = 0; - terminals[curr_tid].screen_x = screen_x; - terminals[curr_tid].screen_y = screen_y; - terminals[curr_tid].cursor_x = screen_x; - terminals[curr_tid].cursor_y = screen_y; - // if (terminals[curr_tid].screen_x == 0 && terminals[curr_tid].screen_y == 0) printf("====== TERMINAL %d ======\n391OS> ", curr_tid); -} - -/* Standard printf(). - * Only supports the following format strings: - * %% - print a literal '%' character - * %x - print a number in hexadecimal - * %u - print a number as an unsigned integer - * %d - print a number as a signed integer - * %c - print a character - * %s - print a string - * %#x - print a number in 32-bit aligned hexadecimal, i.e. - * print 8 hexadecimal digits, zero-padded on the left. - * For example, the hex number "E" would be printed as - * "0000000E". - * Note: This is slightly different than the libc specification - * for the "#" modifier (this implementation doesn't add a "0x" at - * the beginning), but I think it's more flexible this way. - * Also note: %x is the only conversion specifier that can use - * the "#" modifier to alter output. */ -int32_t printf(int8_t *format, ...) { - - /* Pointer to the format string */ - int8_t* buf = format; - - /* Stack pointer for the other parameters */ - int32_t* esp = (void *)&format; - esp++; - - while (*buf != '\0') { - switch (*buf) { - case '%': - { - int32_t alternate = 0; - buf++; - -format_char_switch: - /* Conversion specifiers */ - switch (*buf) { - /* Print a literal '%' character */ - case '%': - putc('%'); - break; - - /* Use alternate formatting */ - case '#': - alternate = 1; - buf++; - /* Yes, I know gotos are bad. This is the - * most elegant and general way to do this, - * IMHO. */ - goto format_char_switch; - - /* Print a number in hexadecimal form */ - case 'x': - { - int8_t conv_buf[64]; - if (alternate == 0) { - itoa(*((uint32_t *)esp), conv_buf, 16); - puts(conv_buf); - } else { - int32_t starting_index; - int32_t i; - itoa(*((uint32_t *)esp), &conv_buf[8], 16); - i = starting_index = strlen(&conv_buf[8]); - while(i < 8) { - conv_buf[i] = '0'; - i++; - } - puts(&conv_buf[starting_index]); - } - esp++; - } - break; - - /* Print a number in unsigned int form */ - case 'u': - { - int8_t conv_buf[36]; - itoa(*((uint32_t *)esp), conv_buf, 10); - puts(conv_buf); - esp++; - } - break; - - /* Print a number in signed int form */ - case 'd': - { - int8_t conv_buf[36]; - int32_t value = *((int32_t *)esp); - if(value < 0) { - conv_buf[0] = '-'; - itoa(-value, &conv_buf[1], 10); - } else { - itoa(value, conv_buf, 10); - } - puts(conv_buf); - esp++; - } - break; - - /* Print a single character */ - case 'c': - putc((uint8_t) *((int32_t *)esp)); - esp++; - break; - - /* Print a NULL-terminated string */ - case 's': - puts(*((int8_t **)esp)); - esp++; - break; - - default: - break; - } - - } - break; - - default: - putc(*buf); - break; - } - buf++; - } - return (buf - format); -} - -/* int32_t puts(int8_t* s); - * Inputs: int_8* s = pointer to a string of characters - * Return Value: Number of bytes written - * Function: Output a string to the console */ -int32_t puts(int8_t* s) { - register int32_t index = 0; - while (s[index] != '\0') { - putc(s[index]); - index++; - } - return index; -} - -// /* void putc(uint8_t c); -// * Inputs: uint_8* c = character to print -// * Return Value: void -// * Function: Output a character to the console */ -// void putc(uint8_t c) { -// cli(); -// screen_x = terminals[curr_schedule].screen_x; -// screen_y = terminals[curr_schedule].screen_y; -// // update_cursor(terminals[curr_tid].screen_x, terminals[curr_tid].screen_y); -// // vid_remap(curr_tid); -// //Newline Case -// if(c == '\n' || c == '\r') { - -// //SCROLL DOWN -// if (screen_y == NUM_ROWS - 1) { -// int x,y; -// uint8_t tmp; -// //Move each row down one -// for (y = 0; y < NUM_ROWS - 1; y++) { -// for (x = 0; x < NUM_COLS; x++) { -// //Put lower row on top -// tmp = *(uint8_t *)(video_mem + ((NUM_COLS * (y + 1) + x) << 1)); -// *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1)) = tmp; -// *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1) + 1) = ATTRIB; -// } -// } - -// //Clear the bottom row -// y = NUM_ROWS - 1; -// for (x = 0; x < NUM_COLS; x++) { -// //Clear current char -// *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1)) = 0; -// *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1) + 1) = ATTRIB; -// } -// screen_y = NUM_ROWS - 1; -// screen_x = 0; - -// } - -// else - -// screen_y++; -// screen_x = 0; -// } - -// //Backspace Case -// else if (c == 8) { -// switch (screen_x) { -// case (0): -// if (screen_y == 0) return; -// default: -// screen_x -= 1; -// terminals[curr_schedule].screen_x = screen_x; -// terminals[curr_schedule].screen_y = screen_y; -// putc(' '); -// screen_x -= 1; - -// } -// screen_x %= NUM_COLS; -// screen_y = (screen_y + (screen_x / NUM_COLS)) % NUM_ROWS; -// } - -// //Normal Print Case -// else { - -// if (screen_x == NUM_COLS - 1) { -// putc('\n'); -// putc(c); -// return; -// } - -// *(uint8_t *)(video_mem + ((NUM_COLS * screen_y + screen_x) << 1)) = c; -// *(uint8_t *)(video_mem + ((NUM_COLS * screen_y + screen_x) << 1) + 1) = ATTRIB; - - - -// screen_x++; -// screen_x %= NUM_COLS; -// screen_y = (screen_y + (screen_x / NUM_COLS)) % NUM_ROWS; -// } -// terminals[curr_schedule].screen_x = screen_x; -// terminals[curr_schedule].screen_y = screen_y; -// terminals[curr_schedule].cursor_x = screen_x; -// terminals[curr_schedule].cursor_y = screen_y; -// // vid_remap(curr_tid); -// // update_cursor(terminals[curr_tid].cursor_x,terminals[curr_tid].cursor_y); -// sti(); -// } - - -// /* void user_putc(uint8_t c); -// * Inputs: uint_8* c = character to print -// * Return Value: void -// * Function: Output a character to the console */ -// void user_putc(uint8_t c) { -// cli(); -// vid_remap(curr_tid); -// screen_x = terminals[curr_tid].screen_x; -// screen_y = terminals[curr_tid].screen_y; -// update_cursor(terminals[curr_tid].screen_x, terminals[curr_tid].screen_y); -// //Newline Case -// if(c == '\n' || c == '\r') { - -// //SCROLL DOWN -// if (screen_y == NUM_ROWS - 1) { -// int x,y; -// uint8_t tmp; -// //Move each row down one -// for (y = 0; y < NUM_ROWS - 1; y++) { -// for (x = 0; x < NUM_COLS; x++) { -// //Put lower row on top -// tmp = *(uint8_t *)(video_mem + ((NUM_COLS * (y + 1) + x) << 1)); -// *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1)) = tmp; -// *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1) + 1) = ATTRIB; -// } -// } - -// //Clear the bottom row -// y = NUM_ROWS - 1; -// for (x = 0; x < NUM_COLS; x++) { -// //Clear current char -// *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1)) = 0; -// *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1) + 1) = ATTRIB; -// } -// screen_y = NUM_ROWS - 1; -// screen_x = 0; - -// } - -// else - -// screen_y++; -// screen_x = 0; -// } - -// //Backspace Case -// else if (c == 8) { -// switch (screen_x) { -// case (0): -// if (screen_y == 0) return; -// default: -// screen_x -= 1; -// terminals[curr_tid].screen_x = screen_x; -// terminals[curr_tid].screen_y = screen_y; -// user_putc(' '); -// screen_x -= 1; - -// } -// screen_x %= NUM_COLS; -// screen_y = (screen_y + (screen_x / NUM_COLS)) % NUM_ROWS; -// } - -// //Normal Print Case -// else { - -// if (screen_x == NUM_COLS - 1) { -// user_putc('\n'); -// user_putc(c); -// return; -// } - -// *(uint8_t *)(video_mem + ((NUM_COLS * screen_y + screen_x) << 1)) = c; -// *(uint8_t *)(video_mem + ((NUM_COLS * screen_y + screen_x) << 1) + 1) = ATTRIB; - - - -// screen_x++; -// screen_x %= NUM_COLS; -// screen_y = (screen_y + (screen_x / NUM_COLS)) % NUM_ROWS; -// } -// terminals[curr_tid].screen_x = screen_x; -// terminals[curr_tid].screen_y = screen_y; -// terminals[curr_tid].cursor_x = screen_x; -// terminals[curr_tid].cursor_y = screen_y; -// update_cursor(terminals[curr_tid].cursor_x,terminals[curr_tid].cursor_y); -// vid_remap(curr_schedule); -// sti(); -// } - - -/* void putc(uint8_t c); - * Inputs: uint_8* c = character to print - * Return Value: void - * Function: Output a character to the console */ -void putc(uint8_t c) { - cli(); - // vid_remap(curr_tid); - screen_x = terminals[curr_tid].screen_x; - screen_y = terminals[curr_tid].screen_y; - update_cursor(terminals[curr_tid].screen_x, terminals[curr_tid].screen_y); - //Newline Case - if(c == '\n' || c == '\r') { - - //SCROLL DOWN - if (screen_y == NUM_ROWS - 1) { - int x,y; - uint8_t tmp; - //Move each row down one - for (y = 0; y < NUM_ROWS - 1; y++) { - for (x = 0; x < NUM_COLS; x++) { - //Put lower row on top - tmp = *(uint8_t *)(video_mem + ((NUM_COLS * (y + 1) + x) << 1)); - *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1)) = tmp; - *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1) + 1) = ATTRIB; - } - } - - //Clear the bottom row - y = NUM_ROWS - 1; - for (x = 0; x < NUM_COLS; x++) { - //Clear current char - *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1)) = 0; - *(uint8_t *)(video_mem + ((NUM_COLS * y + x) << 1) + 1) = ATTRIB; - } - screen_y = NUM_ROWS - 1; - screen_x = 0; - - } - - else - - screen_y++; - screen_x = 0; - } - - //Backspace Case - else if (c == 8) { - switch (screen_x) { - case (0): - if (screen_y == 0) return; - default: - screen_x -= 1; - terminals[curr_tid].screen_x = screen_x; - terminals[curr_tid].screen_y = screen_y; - putc(' '); - screen_x -= 1; - - } - screen_x %= NUM_COLS; - screen_y = (screen_y + (screen_x / NUM_COLS)) % NUM_ROWS; - } - - //Normal Print Case - else { - - if (screen_x == NUM_COLS - 1) { - putc('\n'); - putc(c); - return; - } - - *(uint8_t *)(video_mem + ((NUM_COLS * screen_y + screen_x) << 1)) = c; - *(uint8_t *)(video_mem + ((NUM_COLS * screen_y + screen_x) << 1) + 1) = ATTRIB; - - - - screen_x++; - screen_x %= NUM_COLS; - screen_y = (screen_y + (screen_x / NUM_COLS)) % NUM_ROWS; - } - terminals[curr_tid].screen_x = screen_x; - terminals[curr_tid].screen_y = screen_y; - terminals[curr_tid].cursor_x = screen_x; - terminals[curr_tid].cursor_y = screen_y; - update_cursor(terminals[curr_tid].cursor_x,terminals[curr_tid].cursor_y); - // vid_remap(curr_schedule); - sti(); - -} -/* int8_t* itoa(uint32_t value, int8_t* buf, int32_t radix); - * Inputs: uint32_t value = number to convert - * int8_t* buf = allocated buffer to place string in - * int32_t radix = base system. hex, oct, dec, etc. - * Return Value: number of bytes written - * Function: Convert a number to its ASCII representation, with base "radix" */ -int8_t* itoa(uint32_t value, int8_t* buf, int32_t radix) { - static int8_t lookup[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - int8_t *newbuf = buf; - int32_t i; - uint32_t newval = value; - - /* Special case for zero */ - if (value == 0) { - buf[0] = '0'; - buf[1] = '\0'; - return buf; - } - - /* Go through the number one place value at a time, and add the - * correct digit to "newbuf". We actually add characters to the - * ASCII string from lowest place value to highest, which is the - * opposite of how the number should be printed. We'll reverse the - * characters later. */ - while (newval > 0) { - i = newval % radix; - *newbuf = lookup[i]; - newbuf++; - newval /= radix; - } - - /* Add a terminating NULL */ - *newbuf = '\0'; - - /* Reverse the string and return */ - return strrev(buf); -} - -/* int8_t* strrev(int8_t* s); - * Inputs: int8_t* s = string to reverse - * Return Value: reversed string - * Function: reverses a string s */ -int8_t* strrev(int8_t* s) { - register int8_t tmp; - register int32_t beg = 0; - register int32_t end = strlen(s) - 1; - - while (beg < end) { - tmp = s[end]; - s[end] = s[beg]; - s[beg] = tmp; - beg++; - end--; - } - return s; -} - -/* uint32_t strlen(const int8_t* s); - * Inputs: const int8_t* s = string to take length of - * Return Value: length of string s - * Function: return length of string s */ -uint32_t strlen(const int8_t* s) { - register uint32_t len = 0; - while (s[len] != '\0') - len++; - return len; -} - -/* void* memset(void* s, int32_t c, uint32_t n); - * Inputs: void* s = pointer to memory - * int32_t c = value to set memory to - * uint32_t n = number of bytes to set - * Return Value: new string - * Function: set n consecutive bytes of pointer s to value c */ -void* memset(void* s, int32_t c, uint32_t n) { - c &= 0xFF; - asm volatile (" \n\ - .memset_top: \n\ - testl %%ecx, %%ecx \n\ - jz .memset_done \n\ - testl $0x3, %%edi \n\ - jz .memset_aligned \n\ - movb %%al, (%%edi) \n\ - addl $1, %%edi \n\ - subl $1, %%ecx \n\ - jmp .memset_top \n\ - .memset_aligned: \n\ - movw %%ds, %%dx \n\ - movw %%dx, %%es \n\ - movl %%ecx, %%edx \n\ - shrl $2, %%ecx \n\ - andl $0x3, %%edx \n\ - cld \n\ - rep stosl \n\ - .memset_bottom: \n\ - testl %%edx, %%edx \n\ - jz .memset_done \n\ - movb %%al, (%%edi) \n\ - addl $1, %%edi \n\ - subl $1, %%edx \n\ - jmp .memset_bottom \n\ - .memset_done: \n\ - " - : - : "a"(c << 24 | c << 16 | c << 8 | c), "D"(s), "c"(n) - : "edx", "memory", "cc" - ); - return s; -} - -/* void* memset_word(void* s, int32_t c, uint32_t n); - * Description: Optimized memset_word - * Inputs: void* s = pointer to memory - * int32_t c = value to set memory to - * uint32_t n = number of bytes to set - * Return Value: new string - * Function: set lower 16 bits of n consecutive memory locations of pointer s to value c */ -void* memset_word(void* s, int32_t c, uint32_t n) { - asm volatile (" \n\ - movw %%ds, %%dx \n\ - movw %%dx, %%es \n\ - cld \n\ - rep stosw \n\ - " - : - : "a"(c), "D"(s), "c"(n) - : "edx", "memory", "cc" - ); - return s; -} - -/* void* memset_dword(void* s, int32_t c, uint32_t n); - * Inputs: void* s = pointer to memory - * int32_t c = value to set memory to - * uint32_t n = number of bytes to set - * Return Value: new string - * Function: set n consecutive memory locations of pointer s to value c */ -void* memset_dword(void* s, int32_t c, uint32_t n) { - asm volatile (" \n\ - movw %%ds, %%dx \n\ - movw %%dx, %%es \n\ - cld \n\ - rep stosl \n\ - " - : - : "a"(c), "D"(s), "c"(n) - : "edx", "memory", "cc" - ); - return s; -} - -/* void* memcpy(void* dest, const void* src, uint32_t n); - * Inputs: void* dest = destination of copy - * const void* src = source of copy - * uint32_t n = number of byets to copy - * Return Value: pointer to dest - * Function: copy n bytes of src to dest */ -void* memcpy(void* dest, const void* src, uint32_t n) { - asm volatile (" \n\ - .memcpy_top: \n\ - testl %%ecx, %%ecx \n\ - jz .memcpy_done \n\ - testl $0x3, %%edi \n\ - jz .memcpy_aligned \n\ - movb (%%esi), %%al \n\ - movb %%al, (%%edi) \n\ - addl $1, %%edi \n\ - addl $1, %%esi \n\ - subl $1, %%ecx \n\ - jmp .memcpy_top \n\ - .memcpy_aligned: \n\ - movw %%ds, %%dx \n\ - movw %%dx, %%es \n\ - movl %%ecx, %%edx \n\ - shrl $2, %%ecx \n\ - andl $0x3, %%edx \n\ - cld \n\ - rep movsl \n\ - .memcpy_bottom: \n\ - testl %%edx, %%edx \n\ - jz .memcpy_done \n\ - movb (%%esi), %%al \n\ - movb %%al, (%%edi) \n\ - addl $1, %%edi \n\ - addl $1, %%esi \n\ - subl $1, %%edx \n\ - jmp .memcpy_bottom \n\ - .memcpy_done: \n\ - " - : - : "S"(src), "D"(dest), "c"(n) - : "eax", "edx", "memory", "cc" - ); - return dest; -} - -/* void* memmove(void* dest, const void* src, uint32_t n); - * Description: Optimized memmove (used for overlapping memory areas) - * Inputs: void* dest = destination of move - * const void* src = source of move - * uint32_t n = number of byets to move - * Return Value: pointer to dest - * Function: move n bytes of src to dest */ -void* memmove(void* dest, const void* src, uint32_t n) { - asm volatile (" \n\ - movw %%ds, %%dx \n\ - movw %%dx, %%es \n\ - cld \n\ - cmp %%edi, %%esi \n\ - jae .memmove_go \n\ - leal -1(%%esi, %%ecx), %%esi \n\ - leal -1(%%edi, %%ecx), %%edi \n\ - std \n\ - .memmove_go: \n\ - rep movsb \n\ - " - : - : "D"(dest), "S"(src), "c"(n) - : "edx", "memory", "cc" - ); - return dest; -} - -/* int32_t strncmp(const int8_t* s1, const int8_t* s2, uint32_t n) - * Inputs: const int8_t* s1 = first string to compare - * const int8_t* s2 = second string to compare - * uint32_t n = number of bytes to compare - * Return Value: A zero value indicates that the characters compared - * in both strings form the same string. - * A value greater than zero indicates that the first - * character that does not match has a greater value - * in str1 than in str2; And a value less than zero - * indicates the opposite. - * Function: compares string 1 and string 2 for equality */ -int32_t strncmp(const int8_t* s1, const int8_t* s2, uint32_t n) { - int32_t i; - for (i = 0; i < n; i++) { - if ((s1[i] != s2[i]) || (s1[i] == '\0') /* || s2[i] == '\0' */) { - - /* The s2[i] == '\0' is unnecessary because of the short-circuit - * semantics of 'if' expressions in C. If the first expression - * (s1[i] != s2[i]) evaluates to false, that is, if s1[i] == - * s2[i], then we only need to test either s1[i] or s2[i] for - * '\0', since we know they are equal. */ - return s1[i] - s2[i]; - } - } - return 0; -} - -/* int8_t* strcpy(int8_t* dest, const int8_t* src) - * Inputs: int8_t* dest = destination string of copy - * const int8_t* src = source string of copy - * Return Value: pointer to dest - * Function: copy the source string into the destination string */ -int8_t* strcpy(int8_t* dest, const int8_t* src) { - int32_t i = 0; - while (src[i] != '\0') { - dest[i] = src[i]; - i++; - } - dest[i] = '\0'; - return dest; -} - -/* int8_t* strcpy(int8_t* dest, const int8_t* src, uint32_t n) - * Inputs: int8_t* dest = destination string of copy - * const int8_t* src = source string of copy - * uint32_t n = number of bytes to copy - * Return Value: pointer to dest - * Function: copy n bytes of the source string into the destination string */ -int8_t* strncpy(int8_t* dest, const int8_t* src, uint32_t n) { - int32_t i = 0; - while (src[i] != '\0' && i < n) { - dest[i] = src[i]; - i++; - } - while (i < n) { - dest[i] = '\0'; - i++; - } - return dest; -} - -/* void test_interrupts(void) - * Inputs: void - * Return Value: void - * Function: increments video memory. To be used to test rtc */ -void test_interrupts(void) { - int32_t i; - for (i = 0; i < NUM_ROWS * NUM_COLS; i++) { - video_mem[i << 1]++; - } -} - -/* - * draw_cursor - * Input: tid - * Output: None - * Side Effect: draw cursor on screen - * Reference: https://wiki.osdev.org/Text_Mode_Cursor - */ -void update_cursor(int x, int y) { - uint16_t pos = y * NUM_COLS + x; - - outb(0x0F, 0x3D4); - outb( (uint8_t) (pos & 0xFF), 0x3D5); - outb(0x0E, 0x3D4); - outb( (uint8_t) ((pos >> 8) & 0xFF), 0x3D5); - return; -} -void enable_cursor(uint8_t cursor_start, uint8_t cursor_end) -{ - outb(0x0A, 0x3D4); - outb((inb(0x3D5) & 0xC0) | cursor_start, 0x3D5); - - outb(0x0B, 0x3D4); - outb((inb(0x3D5) & 0xE0) | cursor_end, 0x3D5); -} -void disable_cursor() -{ - outb(0x0A, 0x3D4); - outb(0x20, 0x3D5); -} -uint16_t get_cursor_position(void) -{ - uint16_t pos = 0; - outb(0x0F, 0x3D4); - pos |= inb(0x3D5); - outb(0x0E, 0x3D4); - pos |= ((uint16_t)inb(0x3D5)) << 8; - return pos; -} diff --git a/mp3-LOS/student-distrib/lib.h b/mp3-LOS/student-distrib/lib.h deleted file mode 100644 index 49f0eeb..0000000 --- a/mp3-LOS/student-distrib/lib.h +++ /dev/null @@ -1,176 +0,0 @@ -/* lib.h - Defines for useful library functions - * vim:ts=4 noexpandtab - */ - -#ifndef _LIB_H -#define _LIB_H - -#include "types.h" -extern uint8_t curr_tid; -int32_t printf(int8_t *format, ...); -void putc(uint8_t c); -// void user_putc(uint8_t c); -int32_t puts(int8_t *s); -int8_t *itoa(uint32_t value, int8_t* buf, int32_t radix); -int8_t *strrev(int8_t* s); -uint32_t strlen(const int8_t* s); -void clear(void); - -void* memset(void* s, int32_t c, uint32_t n); -void* memset_word(void* s, int32_t c, uint32_t n); -void* memset_dword(void* s, int32_t c, uint32_t n); -void* memcpy(void* dest, const void* src, uint32_t n); -void* memmove(void* dest, const void* src, uint32_t n); -int32_t strncmp(const int8_t* s1, const int8_t* s2, uint32_t n); -int8_t* strcpy(int8_t* dest, const int8_t*src); -int8_t* strncpy(int8_t* dest, const int8_t*src, uint32_t n); - -// terminal switch helper function -void update_cursor(int x, int y); -void enable_cursor(uint8_t cursor_start, uint8_t cursor_end); -void disable_cursor(); -uint16_t get_cursor_position(void); - - -/* Userspace address-check functions */ -int32_t bad_userspace_addr(const void* addr, int32_t len); -int32_t safe_strncpy(int8_t* dest, const int8_t* src, int32_t n); - -/* Port read functions */ -/* Inb reads a byte and returns its value as a zero-extended 32-bit - * unsigned int */ -static inline uint32_t inb(port) { - uint32_t val; - asm volatile (" \n\ - xorl %0, %0 \n\ - inb (%w1), %b0 \n\ - " - : "=a"(val) - : "d"(port) - : "memory" - ); - return val; -} - -/* Reads two bytes from two consecutive ports, starting at "port", - * concatenates them little-endian style, and returns them zero-extended - * */ -static inline uint32_t inw(port) { - uint32_t val; - asm volatile (" \n\ - xorl %0, %0 \n\ - inw (%w1), %w0 \n\ - " - : "=a"(val) - : "d"(port) - : "memory" - ); - return val; -} - -/* Reads four bytes from four consecutive ports, starting at "port", - * concatenates them little-endian style, and returns them */ -static inline uint32_t inl(port) { - uint32_t val; - asm volatile ("inl (%w1), %0" - : "=a"(val) - : "d"(port) - : "memory" - ); - return val; -} - -/* Writes a byte to a port */ -#define outb(data, port) \ -do { \ - asm volatile ("outb %b1, (%w0)" \ - : \ - : "d"(port), "a"(data) \ - : "memory", "cc" \ - ); \ -} while (0) - -/* Writes two bytes to two consecutive ports */ -#define outw(data, port) \ -do { \ - asm volatile ("outw %w1, (%w0)" \ - : \ - : "d"(port), "a"(data) \ - : "memory", "cc" \ - ); \ -} while (0) - -/* Writes four bytes to four consecutive ports */ -#define outl(data, port) \ -do { \ - asm volatile ("outl %l1, (%w0)" \ - : \ - : "d"(port), "a"(data) \ - : "memory", "cc" \ - ); \ -} while (0) - -/* Clear interrupt flag - disables interrupts on this processor */ -#define cli() \ -do { \ - asm volatile ("cli" \ - : \ - : \ - : "memory", "cc" \ - ); \ -} while (0) - -/* Save flags and then clear interrupt flag - * Saves the EFLAGS register into the variable "flags", and then - * disables interrupts on this processor */ -#define cli_and_save(flags) \ -do { \ - asm volatile (" \n\ - pushfl \n\ - popl %0 \n\ - cli \n\ - " \ - : "=r"(flags) \ - : \ - : "memory", "cc" \ - ); \ -} while (0) - -/* Set interrupt flag - enable interrupts on this processor */ -#define sti() \ -do { \ - asm volatile ("sti" \ - : \ - : \ - : "memory", "cc" \ - ); \ -} while (0) - -/* Restore flags - * Puts the value in "flags" into the EFLAGS register. Most often used - * after a cli_and_save_flags(flags) */ -#define restore_flags(flags) \ -do { \ - asm volatile (" \n\ - pushl %0 \n\ - popfl \n\ - " \ - : \ - : "r"(flags) \ - : "memory", "cc" \ - ); \ -} while (0) - -#define flush_tlb(page_dir) \ -do { \ - asm volatile(" \n\ - movl %0, %%eax \n\ - movl %%eax, %%cr3 \n\ - " \ - : \ - : "r" (page_dir) \ - : "%eax" \ - ); \ -} while (0) - -#endif /* _LIB_H */ diff --git a/mp3-LOS/student-distrib/mp3.img b/mp3-LOS/student-distrib/mp3.img deleted file mode 100644 index 2a7fbde..0000000 Binary files a/mp3-LOS/student-distrib/mp3.img and /dev/null differ diff --git a/mp3-LOS/student-distrib/multiboot.h b/mp3-LOS/student-distrib/multiboot.h deleted file mode 100644 index 231ea52..0000000 --- a/mp3-LOS/student-distrib/multiboot.h +++ /dev/null @@ -1,72 +0,0 @@ -/* multiboot.h - Defines used in working with Multiboot-compliant - * bootloaders (such as GRUB) - * vim:ts=4 noexpandtab - */ - -#ifndef _MULTIBOOT_H -#define _MULTIBOOT_H - -#define MULTIBOOT_HEADER_FLAGS 0x00000003 -#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 -#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 - -#ifndef ASM - -/* Types */ -#include "types.h" - -/* The Multiboot header. */ -typedef struct multiboot_header { - uint32_t magic; - uint32_t flags; - uint32_t checksum; - uint32_t header_addr; - uint32_t load_addr; - uint32_t load_end_addr; - uint32_t bss_end_addr; - uint32_t entry_addr; -} multiboot_header_t; - -/* The section header table for ELF. */ -typedef struct elf_section_header_table { - uint32_t num; - uint32_t size; - uint32_t addr; - uint32_t shndx; -} elf_section_header_table_t; - -/* The Multiboot information. */ -typedef struct multiboot_info { - uint32_t flags; - uint32_t mem_lower; - uint32_t mem_upper; - uint32_t boot_device; - uint32_t cmdline; - uint32_t mods_count; - uint32_t mods_addr; - elf_section_header_table_t elf_sec; - uint32_t mmap_length; - uint32_t mmap_addr; -} multiboot_info_t; - -typedef struct module { - uint32_t mod_start; - uint32_t mod_end; - uint32_t string; - uint32_t reserved; -} module_t; - -/* The memory map. Be careful that the offset 0 is base_addr_low - but no size. */ -typedef struct memory_map { - uint32_t size; - uint32_t base_addr_low; - uint32_t base_addr_high; - uint32_t length_low; - uint32_t length_high; - uint32_t type; -} memory_map_t; - -#endif /* ASM */ - -#endif /* _MULTIBOOT_H */ diff --git a/mp3-LOS/student-distrib/paging.c b/mp3-LOS/student-distrib/paging.c deleted file mode 100644 index f6d019e..0000000 --- a/mp3-LOS/student-distrib/paging.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "paging.h" -#include "lib.h" - -/* - * paging_init(void) - * Initialize paging for kernel.c use - * Inputs: void - * Outputs: none - */ -void paging_init() { - int i; // index for loop - //In this layout everything in the first 4MB, that isn’t the page for video memory, should be marked not present. - SET_PTE(page_table, VIDEO_ADDR / SIZE_4KB, 0, VIDEO_ADDR / SIZE_4KB); - // Checkpoint 5 - for (i = 0; i < MAX_TERMINAL + VIDEO_GAP; i++) { - SET_PTE(page_table, (VIDEO_ADDR / SIZE_4KB + i), 0, VIDEO_ADDR / SIZE_4KB + i); // video pages for terminals - } - - //the first 4 MB of memory should broken down into 4kB pages. (MP3 6.1.5) - SET_PDE(page_dir, 0, 0, 0, 0, ((uint32_t) page_table) / SIZE_4KB); // 4KBs - - /* need only map virtual memory 4-8 MB to physical memory at 4-8 MB, - In addition to 8MB to 4GB being marked not present, you should also set any - unused pages to not present as well. In this layout everything in the first 4MB, - that isn’t the page for video memory, should be marked not present. */ - SET_PDE(page_dir, 1, 0, 1, 1, KERNEL_ADDR / SIZE_4KB);// kernel - - // https://wiki.osdev.org/Paging#32-bit_Paging_.28Protected_Mode.29 - - /*Paging is controlled by three flags in the processor’s control registers: - • PG (paging) flag. Bit 31 of CR0 (available in all IA-32 processors beginning with the Intel386 processor). - • PSE (page size extensions) flag. Bit 4 of CR4 (introduced in the Pentium processor). - • PAE (physical address extension) flag. Bit 5 of CR4 (introduced in the Pentium Proprocessors).*/ - asm volatile( - "movl %0, %%eax; \ - movl %%eax, %%cr3; \ - movl %%cr4, %%eax; \ - orl $0x00000010, %%eax; \ - movl %%eax, %%cr4; \ - movl %%cr0, %%eax; \ - orl $0x80000000, %%eax; \ - movl %%eax, %%cr0;" - : /*no output*/ - : "r" (page_dir) - : "%eax" - ); - - - return; -} - -/* - * vid_remap - * remap the video pages - * Inputs: tid - * Outputs: none - */ -void vid_remap(uint8_t tid) { - - SET_PTE(page_table, VIDEO_ADDR/SIZE_4KB, 0, VIDEO_ADDR/SIZE_4KB); - - // if (tid == curr_tid) { - // SET_PTE(page_table_video, 0, 1,(VIDEO_ADDR/SIZE_4KB)); - // } else { - // SET_PTE(page_table_video, 0, 1,(terminal_pages/SIZE_4KB) + tid); - // } - SET_PTE(page_table_video, 0, 1,(VIDEO_ADDR/SIZE_4KB)); - flush_tlb(page_dir); - return; -} - - diff --git a/mp3-LOS/student-distrib/paging.h b/mp3-LOS/student-distrib/paging.h deleted file mode 100644 index 21754a9..0000000 --- a/mp3-LOS/student-distrib/paging.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef PAGING_H -#define PAGING_H -#include "types.h" -#include "system_calls.h" - -#define TABLE_NUM 1024 // 2 ^ 10 = 1024 -#define PAGE_NUM 1024 // 2 ^ 10 = 1024 -// #define OFFSET_MAX 4096 // 2 ^ 12 = 4096 - -#define SIZE_4KB 4096 // 4 * 1024 = 4096 -#define SIZE_8KB 8192 -#define SIZE_4MB 0x400000 // 4 * 1024 * 1024 = 4194304 = 2 ^ 22 -#define SIZE_8MB 0x800000 -#define SIZE_12MB (SIZE_4MB + SIZE_8MB) -#define SIZE_128MB 0x08000000 -#define SIZE_32MB (8 * SIZE_4MB) - - -#define VIDEO_ADDR 0xB8000 - -#define KERNEL_ADDR SIZE_4MB -#define USER_ADDR SIZE_8MB -#define USER_IMAGE 0x08048000 // The program image itself is linked to execute at virtual address 0x08048000 - -/*The way to get this working is to set up a single 4 MB page directory entry that maps virtual address 0x08000000 (128 MB) to the right -physical memory address (either 8 MB or 12 MB)*/ -#define PROG_START 0x8000000 -#define PROG_END (PROG_START + SIZE_4MB) // 132MB -#define VIDEO_START PROG_END // 132MB -#define IMAGE_ADDR 0x8048000 -#define VIDEO_GAP 2 - -#define SET_PDE(_page_dir, _i, _privilege, _page_size, _global, _addr) do { \ - (_page_dir)[(_i)].present = 1; \ - (_page_dir)[(_i)].read_write = 1; \ - (_page_dir)[(_i)].user_supervisor = (_privilege); \ - (_page_dir)[(_i)].write_through = 0; \ - (_page_dir)[(_i)].cache_disable = 0; \ - (_page_dir)[(_i)].accessed = 0; \ - (_page_dir)[(_i)].reserved = 0; \ - (_page_dir)[(_i)].page_size = (_page_size); \ - (_page_dir)[(_i)].global_page = (_global); \ - (_page_dir)[(_i)].availiable = 0; \ - (_page_dir)[(_i)].page_table_addr = (_addr); \ -} while (0) - -#define SET_PTE(_page_table, _i, _privilege, _addr) do { \ - (_page_table)[(_i)].present = 1; \ - (_page_table)[(_i)].read_write = 1; \ - (_page_table)[(_i)].user_supervisor = (_privilege); \ - (_page_table)[(_i)].write_through = 0; \ - (_page_table)[(_i)].cache_disable = 0; \ - (_page_table)[(_i)].accessed = 0; \ - (_page_table)[(_i)].dirty = 0; \ - (_page_table)[(_i)].pat_index = 0; \ - (_page_table)[(_i)].global_page = 0; \ - (_page_table)[(_i)].availiable = 0; \ - (_page_table)[(_i)].page_addr = (_addr); \ -} while (0) - -typedef struct __attribute__((packed)) pde_desc { // Page-Directory Entry (Vol.3 3-24 p90) - uint32_t present : 1; // Indicates whether the page or page table being pointed to by the entry is currently loaded in physical memory. - uint32_t read_write : 1; // Specifies the read-write _privileges for a page or group of pages: 0 - read only; 1 - read and write - uint32_t user_supervisor : 1; // 0 - supervisor, 1 - user - uint32_t write_through : 1; // 0 - write back, 1 - write through - uint32_t cache_disable : 1; // 0 - can be cached, 1 - cache is prevented - uint32_t accessed : 1; - uint32_t reserved : 1; // (set to 0) - uint32_t page_size : 1; // (0 indicates 4 KBytes) - uint32_t global_page : 1; // (Ignored) - uint8_t availiable : 3; // bit 11 - 9 - uint32_t page_table_addr : 20; // bit 31 - 12 -}pde_desc_t; - -typedef struct __attribute__((packed)) pte_desc { // Page-Table Entry (Vol.3 3-24 p90) - uint32_t present : 1; - uint32_t read_write : 1; - uint32_t user_supervisor : 1; - uint32_t write_through : 1; - uint32_t cache_disable : 1; - uint32_t accessed : 1; - uint32_t dirty : 1; - uint32_t pat_index : 1; // page attribute table index, bit 7 in ptes for 4KB pages and bit 12 in pdes for 4MB pages - uint32_t global_page : 1; - uint8_t availiable : 3; // bit 11 - 9 - uint32_t page_addr : 20; // bit 31 - 12 -}pte_desc_t; - - -// to innitialize paging (used in kernel.c) -void paging_init(void); - -void vid_remap(uint8_t tid); - -/*To align things in C: int some_variable __attribute__((aligned (BYTES_TO_ALIGN_TO)));*/ -pde_desc_t page_dir[TABLE_NUM] __attribute__((aligned (SIZE_4KB))); -pte_desc_t page_table[PAGE_NUM] __attribute__((aligned (SIZE_4KB))); -pte_desc_t page_table_kernel[PAGE_NUM] __attribute__((aligned (SIZE_4KB))); -pte_desc_t page_table_video[PAGE_NUM] __attribute__((aligned (SIZE_4KB))); -#endif diff --git a/mp3-LOS/student-distrib/pit.c b/mp3-LOS/student-distrib/pit.c deleted file mode 100644 index 5cd0cc3..0000000 --- a/mp3-LOS/student-distrib/pit.c +++ /dev/null @@ -1,58 +0,0 @@ -#define pit_data_port_0 0x40 -#define pit_command 0x36 -#define freq 20 -#define pit_IRQ_num 0 -#define BASE_FREQ 11931820 - -#include "pit.h" -#include "x86_desc.h" -#include "lib.h" -#include "i8259.h" - -unsigned int counter; - -/* - * pit_init - * Initialize the Programmable Interval Timer (PIT). PIT oscillator chip runs at - * about 1.193182 MHz freq, which is the set base frequency. Dividing this freq will - * derive other desired frequencies. - * Inputs: None - * Outputs: None - * Side Effects: Enables IRQ0 to use for PIT - */ -void pit_init() { - int divided; - divided = BASE_FREQ / freq; - enable_irq(pit_IRQ_num); - - /* Set command byte - Bits 6-7: 00 = Channel 0 - Bits 4-5: 11 = Access mode lobyte/hibyte - Bits 1-3: 011 = Mode 3 (Square Wave Generator) - Bit 0: 0 = 16-bit binary mode (values x0000 - xFFFF for counter) - pit_command = 00 11 011 0 = x36 */ - outb(pit_command, pit_data_port_0); - - // Write to low byte first (lobyte/hibyte access mode) - outb(divided & 0xFF, pit_data_port_0); - - // Write to high byte second - outb((divided & 0xFF00) >> 8, pit_data_port_0); - - counter = 0; -} - -void pit_interrupt_handler() { - cli(); - // printf("%u\n", counter); - // if (counter % 20 == 0) printf("%u\n", counter); - counter++; - - send_eoi(pit_IRQ_num); - // printf("do schedule\n"); - sti(); - if (counter % 2 == 0) { - // scheduler_rr(); - } - -} diff --git a/mp3-LOS/student-distrib/pit.h b/mp3-LOS/student-distrib/pit.h deleted file mode 100644 index e26780a..0000000 --- a/mp3-LOS/student-distrib/pit.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef PIT_H -#define PIT_H - -#include "scheduler.h" - -// Reference: https://wiki.osdev.org/PIT -extern void pit_init(); - -#endif diff --git a/mp3-LOS/student-distrib/rtc.c b/mp3-LOS/student-distrib/rtc.c deleted file mode 100644 index 416de3a..0000000 --- a/mp3-LOS/student-distrib/rtc.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "rtc.h" -#include "lib.h" -#include "i8259.h" -#include "types.h" -#define FREQ 1024 -// bool INTERRUPT_HAPPEN; - -/* - * rtc_init(void) - * Initialize rtc - * Inputs: void - * Outputs: none - */ -void rtc_init() { //https://wiki.osdev.org/RTC - unsigned char prev; - - //cli(); - outb(RTC_REG_B, RTC_PORT); // select register B, and disable NMI - prev = inb(RTC_W_PORT); // read the current value of register B - outb(RTC_REG_B,RTC_PORT); // set the index again (a read will reset the index to register D) - outb(prev | BIT_SIX, RTC_W_PORT); // write the previous value ORed with 0x40. This turns on bit 6 of register B - enable_irq(RTC_IRQ_NUM); - - // outb(RTC_REG_A, RTC_PORT); // selecting register A and disabling NMI's - // char save = inb(RTC_W_PORT); // reading previous value of A - // outb(RTC_REG_A ,RTC_PORT); // selecting A again - // outb(((save & 0xF0) | 15), RTC_W_PORT); // getting correct rate - num_interrupts_needed = FREQ; - num_interrupts_generated = 0; - rtc_read_flag = 0; - //sti(); - -} - - -/* - * void rtc_interrupt_handler() - * Handles an RTC interrupt when it happens - * Inputs: none - * Outputs: returns 1 - */ -void rtc_interrupt_handler() { - - // printf("RTC"); - - cli(); - if(num_interrupts_generated == num_interrupts_needed){ - rtc_read_flag = 1; - // printf("ret 11111\n"); - num_interrupts_generated = 0; - // printf("RTCif"); - }else{ - num_interrupts_generated = num_interrupts_generated + 1; - } - outb((RTC_REG_C), RTC_PORT); // select register C - // printf("RTC1"); - inb(RTC_W_PORT); // toss the contents - // printf("RTC2"); - send_eoi(RTC_IRQ_NUM); // end of interrupt - // printf("RTC3"); - //rtc_open(NULL); - sti(); - // printf("RTC4"); - // test_interrupts(); - - // INTERRUPT_HAPPEN = 1; // sending signal that an interrupt happened -} - -/* - * int32_t rtc_read(int32_t fd, void* buf, int32_t nbytes) - * Waits for an interrupt and then returns 0 - * Inputs: fd (ignored), buf (ignored), nbytes (ignored) - * Outputs: returns zero - */ -int32_t rtc_read(int32_t fd, void* buf, int32_t nbytes){ - // rtc_read_flag = 0; - printf(""); // for whatever reason removing this print breaks the rtc... - while(rtc_read_flag != 1); - rtc_read_flag = 0; // resetting signal - return 0; -} - -/* - * int32_t write(int32_t fd, const void* buf, int32_t) - * Changes the frequency of the RTC interrupts without changing the RTC's ability to keep time - * Inputs: fd (ignored), buf (pointer to requested frequency), nbytes (ignored) - * Outputs: returns zero on success and -1 on failure - */ -int32_t rtc_write(int32_t fd, const void* buf, int32_t nbytes){ - - uint32_t rate = *(uint32_t*) buf; - - if(rate < 2 || rate > FREQ){ - return -1; // rate is outside allowed range - } - if((rate & ((rate-1))) != 0){ - return -1; // is not a power of two - } - num_interrupts_needed = FREQ/rate; - // // uint32_t divider = divider_calc(rate); - // uint32_t divider; - - // divider = 32768 << rate; - // divider--; - // // if(rate == 2){ divider = 15; } // calculating correct divider - // // else if(rate == 4){ divider = 14; } - // // else if(rate == 8){ divider = 13; } - // // else if(rate == 16){ divider = 12; } - // // else if(rate == 32){ divider = 11; } - // // else if(rate == 64){ divider = 10; } - // // else if(rate == 128){ divider = 9; } - // // else if(rate == 256){ divider = 8; } - // // else if(rate == 512){ divider = 7; } - // // else{ divider = 6; } - - // cli(); - // outb(RTC_REG_A, RTC_PORT); // selecting register A and disabling NMI's - // char prev = inb(RTC_W_PORT); // reading previous value of A - // outb(RTC_REG_A ,RTC_PORT); // selecting A again - // outb(((prev & 0xF0) | divider), RTC_W_PORT); // writing only bottom 4 bits of register A - // // ANDing prev with 0xF0 saves the highest four - // // bits of the previous value of A, then ORing - // // sets the new desired rate into the lowest bits - // sti(); - - return 0; // success! -} - - -/* - * int32_t rtc_open(const uint_t* filename) - * resets the RTC to the default frequency (2Hz) - * Inputs: filename (ignored) - * Outputs: returns 0 - */ -int32_t rtc_open(const uint8_t* filename){ - num_interrupts_generated = 0; - // num_interrupts_needed = FREQ/2; - return 0; -} - - -/* - * int32_t rtc_close(int32_t fd) - * does nothing - * Inputs: fd (ignored) - * Outputs: returns 0 - */ -int32_t rtc_close(int32_t fd){ - return 0; -} diff --git a/mp3-LOS/student-distrib/rtc.h b/mp3-LOS/student-distrib/rtc.h deleted file mode 100644 index 451dba0..0000000 --- a/mp3-LOS/student-distrib/rtc.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef RTC_H -#define RTC_H - -#include "types.h" - -/*The 2 IO ports used for the RTC and CMOS are 0x70 and 0x71. Port 0x70 is used to specify an index or "register number", -and to disable NMI. Port 0x71 is used to read or write from/to that byte of CMOS configuration space. -Only three bytes of CMOS RAM are used to control the RTC periodic interrupt function. -They are called RTC Status Register A, B, and C. They are at offset 0xA, 0xB, and 0xC in the CMOS RAM. */ -#define RTC_PORT 0x70 -#define RTC_W_PORT 0x71 -#define RTC_REG_A 0x8A // RegA and disable NMI -#define RTC_REG_B 0x8B -#define RTC_REG_C 0x8C - -#define DISABLE_NMI 0x80 - -#define RTC_IRQ_NUM 8 -#define BIT_SIX 0x40 -#define RTC_MAX_RATE 32768 - -int num_interrupts_needed; -int num_interrupts_generated; -int rtc_read_flag; - -// initialize rtc -void rtc_init(void); - -// RTC interrupt handler -void rtc_interrupt_handler(void); - -// checkpoint 2 functions -int32_t rtc_write(int32_t fd, const void* buf, int32_t nbytes); -int32_t rtc_read(int32_t fd, void* buf, int32_t nbytes); -int32_t rtc_open(const uint8_t* filename); -int32_t rtc_close(int32_t fd); - -// helper for write -// uint32_t divider_calc(uint32_t rate); - -#endif diff --git a/mp3-LOS/student-distrib/scheduler.c b/mp3-LOS/student-distrib/scheduler.c deleted file mode 100644 index e5c6162..0000000 --- a/mp3-LOS/student-distrib/scheduler.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "scheduler.h" -uint8_t curr_schedule = 0; -volatile int32_t count; -/* - * scheduler_init - * initialize scheduler - * Input: None - * Output: None - */ -void scheduler_init() { - int i; - curr_schedule = 0; - count = 2; - for (i = 0; i < MAX_SCHEDULE; i++) // init all in schedules_rr to -2 - schedules_rr[i] = -1; - return; -} -/* - * scheduler_rr - * Round Robin scheduler - * Input: None - * Output: None - */ -void scheduler_rr() { - // int next_schedule = 0; - // int32_t next_pid; - // /* ==================CALCULATE PCB================== */ - // register int32_t esp_value asm("esp"); - // register uint32_t ebp_value asm("ebp"); - // uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - // pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - // pcb_t* next_pcb; - // cur_pcb->esp_s = esp_value; - // cur_pcb->ebp_s = ebp_value; - // printf("current ebp: %d, esp: %d",ebp_value, esp_value); - // curr_schedule = (curr_schedule + 1) % MAX_SCHEDULE; // Round Robin - // next_pid = schedules_rr[(int32_t)curr_schedule]; - // next_pcb = (pcb_t*)(SIZE_8MB - (next_pid + 1) * SIZE_8KB); - // printf(" ---- ter: %d, pid: %d\n", curr_schedule, next_pid); - - // if (next_pid == -2) { - // // return; - // // vid_remap(curr_schedule); - // execute((uint8_t*)"shell"); - // } - // vid_remap(curr_schedule); - // else if (next_pid == 0) { - // printf("schedule terminal0!\n"); - // } - // else if (next_pid == 1) { - // printf("schedule terminal1!\n"); - // } - // curr_schedule = cur_pcb->curr_pid; - - // if (schedules_rr[curr_schedule] == -2) { // first switch - // map virtual video memory(4KB) to reserve physical video page for terminal# (next_schedule) - // SET_PTE(page_table, VIDEO_ADDR/SIZE_4KB, 0, VIDEO_ADDR/SIZE_4KB + VIDEO_GAP + curr_schedule); - // SET_PTE(page_table_video, 0, 1, VIDEO_ADDR/SIZE_4KB + VIDEO_GAP + curr_schedule); - // SET_PDE(page_dir, PROG_START/SIZE_4MB, 1, 1, 0, (SIZE_8MB + curr_schedule * SIZE_4MB)/SIZE_4KB); - // vid_remap(curr_schedule); - // printf("current schedule = %d", curr_schedule); - // execute((uint8_t*)"shell"); - // } - // if (count > 0) { - // vid_remap(curr_schedule); - // execute((uint8_t*)"shell"); - // printf("count = %d", count); - // count--; - // } - register uint32_t ebp_value asm("ebp"); - register uint32_t esp_value asm("esp"); - uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - pcb_t* next_pcb; - cur_pcb->ebp_s = ebp_value; - - int32_t next_pid; - curr_schedule = (curr_schedule + 1) % MAX_SCHEDULE; // Round Robin - - int j; - for (j = 0; j < MAX_PROCESS; j++) { - if (tid_pids[curr_schedule][j] == -1) - break; - } - if (j == 0) return; - next_pid = tid_pids[curr_schedule][j-1]; - - - next_pcb = (pcb_t*)(SIZE_8MB - (next_pid+ 1) * SIZE_8KB); - - // map virtual program image (128MB) to physical user program (shell# 8MB-12MB-16MB) - SET_PDE(page_dir, PROG_START/SIZE_4MB, 1, 1, 0, (SIZE_8MB + (next_pid * SIZE_4MB)) / SIZE_4KB); - - /* Flush TLB */ - flush_tlb(page_dir); - - // vid_remap(curr_schedule); - // Write Parent Process Info Back into TSS - tss.ss0 = KERNEL_DS; - tss.esp0 = (uint32_t)(SIZE_8MB - (next_pid) * SIZE_TASK) - 4; - asm volatile(" \n\ - movl %0, %%ebp \n\ - leave \n\ - ret" - : /* no output */ - : "r" (next_pcb->ebp_s) - :"ebp"); -} diff --git a/mp3-LOS/student-distrib/scheduler.h b/mp3-LOS/student-distrib/scheduler.h deleted file mode 100644 index d7fc12b..0000000 --- a/mp3-LOS/student-distrib/scheduler.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SCHEDULE_H -#define SCHEDULE_H -#include "types.h" -#include "paging.h" -#include "x86_desc.h" -#include "lib.h" -#include "terminal_driver.h" -#include "filesys.h" -#include "system_calls.h" - -#define MAX_SCHEDULE 3 -extern void scheduler_init(); -extern void scheduler_rr(); - - -int schedules_rr[MAX_SCHEDULE]; - - -#endif diff --git a/mp3-LOS/student-distrib/system_calls.c b/mp3-LOS/student-distrib/system_calls.c deleted file mode 100644 index dfd4959..0000000 --- a/mp3-LOS/student-distrib/system_calls.c +++ /dev/null @@ -1,457 +0,0 @@ -#include "system_calls.h" -#include "i8259.h" -int32_t curr_pid; -uint8_t curr_tid = 0; -uint8_t vid_tid = 0; -/* pid_init - * Inputs: status - * Outputs: 0 - success - * Functionality: initialize the pid - */ -void pid_init() { - int i, j; - for (j = 0; j < MAX_PROCESS; j++) { - pids[j] = 0; - } - for (i = 0; i < MAX_SHELL; i++) { - for (j = 0; j < MAX_PROCESS; j++) { - tid_pids[i][j] = -1; - // printf("tid_pids[%d][%d] == %d ",i,j,tid_pids[i][j]); - } - printf("\n"); - } -} - -/* int32_t halt (uint8_t status) - * Inputs: status - * Outputs: 0 - success - * Functionality: exit currnt process - */ -int32_t halt (uint8_t status){ - int i, j; // index to loop the files - - /* ==================CALCULATE PCB================== */ - // register int32_t esp_value asm("esp"); - // uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - // pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - uint32_t cur_pid; - pcb_t* cur_pcb; - for (j = 0; j < MAX_PROCESS; j++) { - if (tid_pids[curr_tid][j] == -1) - break; - } - if (j == 1) { - printf("Do not exit the last shell!\n"); - cur_pid = tid_pids[curr_tid][0]; - cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - tid_pids[curr_tid][0] = -1; - pids[cur_pcb->curr_pid] = 0; - execute((uint8_t*)"shell"); - } - if (j == 0) { - printf("No shell yet!\n"); - execute((uint8_t*)"shell"); - } - j--; - cur_pid = tid_pids[curr_tid][j]; - cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - - pids[cur_pid] = 0; - tid_pids[curr_tid][cur_pcb->pid_in_t] = -1; - - schedules_rr[curr_schedule] = cur_pcb->parent_pid; - // printf("j = %d, cur_pcb->pid_in_t = %d\n",j, cur_pcb->pid_in_t); - // pcb_t* par_pcb = (pcb_t*)(SIZE_8MB - (cur_pcb->parent_pid + 1) * SIZE_8KB); - if (cur_pcb->parent_pid == -1){ - printf("Do not exit the last shell\n"); - pids[cur_pcb->curr_pid] = 0; - execute((uint8_t*)"shell"); - } - - // for(i = 0; i < MAX_SCHEDULE; i++){ - // if(schedules_rr[i] == cur_pid) - // schedules_rr[i] = cur_pcb->parent_pid; - // } - - - //-----Restore Parent Data-----// - //(todo) - - //-----Restore Parent Paging-----// - // printf("%d\n", cur_pcb->parent_pid); - // (page_dir)[SIZE_128MB >> 22].present = 0; - SET_PDE(page_dir, PROG_START/SIZE_4MB, 1, 1, 0, (SIZE_8MB + ((cur_pcb->parent_pid) * SIZE_4MB)) / SIZE_4KB); - // printf("Set pde.\n"); - //-----Clear FD Array-----// - for (i = 0; i < MAX_PCB_FILES; i++) { - if (cur_pcb->file_descs[i].flags == 1) { - cur_pcb->file_descs[i].file_ops_ptr.close_f(i); - cur_pcb->file_descs[i].flags = 0; - } - } - - /* Flush TLB */ - flush_tlb(page_dir); - //-----Write Parent Process Info Back into TSS-----// - tss.ss0 = KERNEL_DS; - tss.esp0 = (uint32_t)(SIZE_8MB - (cur_pcb->parent_pid) * SIZE_TASK) - 4; - //-----Jump to Execute Return-----// - //(todo) - asm volatile(" \n\ - movl %0, %%eax \n\ - movl %1, %%ebp \n\ - leave \n\ - ret" - : /* no output */ - : "r" ((uint32_t)status),\ - "r" (cur_pcb->ebp) - : "eax", "ebp"); - // printf("exit return 0\n"); - return 0; -} - -/* int32_t execute (const uint8_t* command) - * Inputs: command - * Outputs: 0 - success - * Functionality: create a process - */ -int32_t execute (const uint8_t* command){ - - int32_t i, j; - int32_t prog_buf, child_pid; - dentry_t dentry_buf; - pcb_t* child_pcb; - uint8_t elf_buf[4]; /* Testing ELF needs 4 bytes */ - int data_len = 4; - uint8_t program_name[FNAME_MAX] = {'\0'}; - int8_t args[NUM_CHARS + 1] = {'\0'}; - - // uint32_t freq = 2; - // disable_irq(RTC_IRQ_NUM); - - /* ==================SANITY CHECK================== */ - if (command == NULL) { - printf("Please type command!\n"); - return -1; - } - - /*Store first word of command as the program name */ - for (i = 0; i < strlen((int8_t*)command) && command[i] != '\0' && command[i] != ' '; i++) - program_name[i] = command[i]; - /* Find length of remaining command string increment in index i */ - while (i < strlen((int8_t*)command) && command[i] != '\0' && command[i] == ' ') // skip space between program and args - i++; - /* Given length store in args buffer with preset max size */ - for (j = 0; i < strlen((int8_t*)command) && command[i] != '\0';) - args[j++] = command[i++]; - - /* Check file validity */ - if (read_dentry_by_name(program_name, &dentry_buf) == -1) - return -1; - - /*The first 4 bytes of the file represent a “magic number” that identifies the file as an executable. These bytes are, respectively, 0: 0x7f; 1: 0x45; 2: 0x4c; 3: 0x46. - If the magic number is not present, the execute system call should fail.*/ - if(4 != read_data((uint32_t)(dentry_buf.inode_num), (uint32_t)0, (uint8_t*)elf_buf, (uint32_t*)(&data_len))) - return -1; - if (elf_buf[0] != 0x7f || elf_buf[1] != 0x45 || elf_buf[2] != 0x4c || elf_buf[3] != 0x46) - return -1; - // printf("read data\n"); - - /* ==================LOAD DATA================== */ - /* Program start address which is in 24-27 bytes */ - read_data((uint32_t)(dentry_buf.inode_num), (uint32_t)24, (uint8_t*)(&prog_buf), (uint32_t*)(&data_len)); - // printf("read data\n"); - /* ==================CHECK EDGE CASES================== */ - for (j = 0; j < MAX_PROCESS; j++) { - if (tid_pids[curr_tid][j] == -1) - break; - } - for (i = 0; i < MAX_PROCESS; i++) { - if (pids[i] == 0) - break; - } - // printf("curr_tid = %d, pid = %d, pid in termianl = %d, program_name = %s\n", curr_tid, i, j, program_name); - // if (i >= MAX_SHELL && strncmp((int8_t*)program_name,(int8_t*)"shell",6) == 0) { - // printf("Reach max shell!\n"); - // return -1; - // } - if (i >= MAX_PROCESS) { - printf("Reach max process!\n"); - return -1; - } - // if (strncmp((int8_t*)program_name,(int8_t*)"fish",5) == 0 || strncmp((int8_t*)program_name,(int8_t*)"pingpong",9) == 0) { - // rtc_init(); - - // rtc_write(0, &freq, 0); - // } - /* ==================INIT PCB================== */ - /* Set child_pcb and pid */ - pids[i] = 1; - tid_pids[curr_tid][j] = i; - child_pid = i; - child_pcb = (pcb_t*)(SIZE_8MB - (child_pid + 1) * SIZE_TASK); - child_pcb->curr_pid = child_pid; - child_pcb->pid_in_t = j; - /* Child pid becomes current pid, save esp value*/ - register uint32_t esp_value asm("esp"); - register uint32_t ebp_value asm("ebp"); - child_pcb->esp = esp_value; - child_pcb->ebp = ebp_value; - // uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_TASK; - // pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_TASK); - - /* Check if child is the first pid */ - // if(child_pid == 0 || child_pid == 1 || child_pid == 2){ - // child_pcb->parent_pid = -1; - // }else{ - // child_pcb->parent_pid = cur_pcb->curr_pid; - // } - if (j == 0) { - child_pcb->parent_pid = -1; - } else { - child_pcb->parent_pid = tid_pids[curr_tid][j - 1]; - // printf("cur_pcb->curr_pid = %d, tid_pids[curr_tid][j] = %d\n", cur_pcb->curr_pid, tid_pids[curr_tid][j - 1]); - } - - // curr_tid = (uint8_t)child_pid; - // printf("current tid = %d", curr_tid); - - /* Copy arguments into configured child pcb */ - memcpy(child_pcb->args, args, NUM_CHARS + 1); - - /* Configure file descriptors in the following for stdin and stout respectively */ - - child_pcb->file_descs[0].file_ops_ptr.close_f = terminal_bad_close; - child_pcb->file_descs[0].file_ops_ptr.open_f = terminal_bad_open; - child_pcb->file_descs[0].file_ops_ptr.read_f = (read_ptr)terminal_read; - child_pcb->file_descs[0].file_ops_ptr.write_f = terminal_bad_write; - child_pcb->file_descs[0].inode = 0; - child_pcb->file_descs[0].file_pos = 0; - child_pcb->file_descs[0].flags = 1; - - child_pcb->file_descs[1].file_ops_ptr.close_f = terminal_bad_close; - child_pcb->file_descs[1].file_ops_ptr.read_f = terminal_bad_read; - child_pcb->file_descs[1].file_ops_ptr.open_f = terminal_bad_open; - child_pcb->file_descs[1].file_ops_ptr.write_f = (write_ptr)terminal_write; - child_pcb->file_descs[1].inode = 0; - child_pcb->file_descs[1].file_pos = 0; - child_pcb->file_descs[1].flags = 1; - - /* ==================SET SCHEDULE================== */ - - schedules_rr[curr_schedule] = child_pid; - // if(schedules_rr[curr_schedule] == -2 || schedules_rr[curr_schedule] == child_pcb->parent_pid) - // schedules_rr[curr_schedule] = child_pcb->curr_pid; - // for(i = 0; i < MAX_SCHEDULE; i++){ - // if(schedules_rr[i] == -2 || schedules_rr[i] == child_pcb->parent_pid){ - // schedules_rr[i] = child_pid; - // break; - // } - // } - /* ==================SET PAGING================== */ - SET_PDE(page_dir, SIZE_128MB/SIZE_4MB, 1, 1, 0, (SIZE_8MB + child_pid * SIZE_4MB)/SIZE_4KB); // index 128/4 = 32, user program start at 8MB, 4MB each - /* Flush TLB */ - flush_tlb(page_dir); - // vid_remap(curr_tid); - // SET_PTE(page_table, VIDEO_ADDR/SIZE_4KB, 0, VIDEO_ADDR/SIZE_4KB); - // SET_PTE(page_table_video, 0, 1,(VIDEO_ADDR/SIZE_4KB)); - // flush_tlb(page_dir); - - data_len = PROG_END - IMAGE_ADDR; - read_data((uint32_t)(dentry_buf.inode_num), (uint32_t)0, (uint8_t*)(IMAGE_ADDR), (uint32_t*)(&data_len)); - - tss.ss0 = KERNEL_DS; - tss.esp0 = (uint32_t)(SIZE_8MB - (child_pid) * SIZE_TASK) - 4; - - /*Enabling the cursor also allows you to set the start and end scanlines, - the rows where the cursor starts and ends. - The highest scanline is 0 and the lowest scanline is the maximum scanline (usually 15).*/ - // enable_cursor(14, 15); - - sti(); - - asm volatile(" \n\ - pushl %0 \n\ - pushl %1 \n\ - pushfl \n\ - pushl %2 \n\ - pushl %3 \n\ - iret \n\ - " - : /* no output */ \ - : "r" (USER_DS), \ - "r" (PROG_END - 4),\ - "r" (USER_CS), \ - "r" (prog_buf) \ - : "memory"); - // enable_irq(RTC_IRQ_NUM); - return 0; -} -/* int32_t read (int32_t fd, void* buf, int32_t nbytes) - * Inputs: int32_t fd, void* buf, int32_t nbytes - * Outputs: 0 - success - * Functionality: read a file - */ -int32_t read (int32_t fd, void* buf, int32_t nbytes) { - /* ==================CALCULATE PCB================== */ - register int32_t esp_value asm("esp"); - uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - int32_t read_count = 0; - if (fd < 0 || fd >= MAX_PCB_FILES || buf == NULL || nbytes <= 0 || !(cur_pcb->file_descs[fd].flags)) - return -1; - read_count = cur_pcb->file_descs[fd].file_ops_ptr.read_f(fd, buf, nbytes); - cur_pcb->file_descs[fd].file_pos += read_count; - return read_count; -} - -/* int32_t write (int32_t fd, void* buf, int32_t nbytes) - * Inputs: int32_t fd, void* buf, int32_t nbytes - * Outputs: 0 - success - * Functionality: write a file - */ -int32_t write (int32_t fd, const void* buf, int32_t nbytes){ - /* ==================CALCULATE PCB================== */ - register int32_t esp_value asm("esp"); - uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - - if (fd < 0 || fd >= MAX_PCB_FILES || buf == NULL || nbytes <= 0 ||!(cur_pcb->file_descs[fd].flags)) - return -1; - return cur_pcb->file_descs[fd].file_ops_ptr.write_f(fd, buf, nbytes); -} - -/* int32_t open (const uint8_t* filename) - * Inputs: const uint8_t* filename - * Outputs: 0 - success - * Functionality: open a file - */ -int32_t open (const uint8_t* filename) { - int i = 0; - int fd; - dentry_t dentry; - /* if filaname invalid, -1*/ - if (fopen(filename) == -1) return -1; - - /* ==================CALCULATE PCB================== */ - register int32_t esp_value asm("esp"); - uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - - while (i < MAX_PCB_FILES && cur_pcb->file_descs[i].flags) - i++; - if (i == MAX_PCB_FILES) return -1; // check valid file space - - fd = i; - read_dentry_by_name(filename, &dentry); - cur_pcb->file_descs[fd].flags = 1; - cur_pcb->file_descs[fd].inode = dentry.inode_num; - cur_pcb->file_descs[fd].file_pos = 0; - switch (dentry.filetype) - { - case 0: // rtc - cur_pcb->file_descs[fd].file_ops_ptr.open_f = rtc_open; - cur_pcb->file_descs[fd].file_ops_ptr.close_f = rtc_close; - cur_pcb->file_descs[fd].file_ops_ptr.read_f = rtc_read; - cur_pcb->file_descs[fd].file_ops_ptr.write_f = rtc_write; - break; - case 1: // directory - cur_pcb->file_descs[fd].file_ops_ptr.open_f = dopen; - cur_pcb->file_descs[fd].file_ops_ptr.close_f = dclose; - cur_pcb->file_descs[fd].file_ops_ptr.read_f = dread; - cur_pcb->file_descs[fd].file_ops_ptr.write_f = dwrite; - break; - case 2: // file - cur_pcb->file_descs[fd].file_ops_ptr.open_f = fopen; - cur_pcb->file_descs[fd].file_ops_ptr.close_f = fclose; - cur_pcb->file_descs[fd].file_ops_ptr.read_f = fread; - cur_pcb->file_descs[fd].file_ops_ptr.write_f = fwrite; - break; - default: - cur_pcb->file_descs[fd].flags = 0; - return -1; - break; - } - cur_pcb->file_descs[fd].file_ops_ptr.open_f(filename); - return fd; -} -/* int32_t close (int32_t fd) - * Inputs: int32_t fd - * Outputs: 0 - success - * Functionality: close a file - */ -int32_t close (int32_t fd){ - if (fd <= 1 || fd >= MAX_PCB_FILES) return -1; - /* ==================CALCULATE PCB================== */ - register int32_t esp_value asm("esp"); - uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - - if (!cur_pcb->file_descs[fd].flags) return -1; - - cur_pcb->file_descs[fd].file_ops_ptr.close_f(fd); - cur_pcb->file_descs[fd].flags = 0; - - return 0; -} -/* int32_t getargs (uint8_t* buf, int32_t nbytes) - * Inputs: uint8_t* buf, int32_t nbytes - * Outputs: 0 - success - * Functionality: get arguments, from excute - */ -int32_t getargs (uint8_t* buf, int32_t nbytes){ - /* ==================CALCULATE PCB================== */ - register int32_t esp_value asm("esp"); - uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - - if(buf == NULL || nbytes <= 0 || (uint32_t)buf < PROG_START || cur_pcb == NULL || cur_pcb->args[0] == '\0') - return -1; - if (nbytes > NUM_CHARS) nbytes = NUM_CHARS; - - memcpy(buf, cur_pcb->args, nbytes); - // puts((int8_t*)buf); - // printf("\n"); - - return 0; -} - -/* int32_t vidmap (uint8_t** screen_start) - * Inputs: uint8_t** screen_start - * Outputs: 0 - success - * Functionality: set video map - */ -int32_t vidmap (uint8_t** screen_start){ - - if (screen_start == NULL || screen_start < (uint8_t**) PROG_START || - screen_start > (uint8_t**) (PROG_END - 1)) - return -1; - /* Set new page directory entry from virtual video address to physical video memory */ - SET_PDE(page_dir, PROG_END/SIZE_4MB, 1, 0, 0, (uint32_t) (page_table_video) / SIZE_4KB); // index 132/4 = 33 - - SET_PTE(page_table_video, 0, 1,(VIDEO_ADDR/SIZE_4KB)); - vid_tid = curr_tid; - /* Flush TLB */ - flush_tlb(page_dir); - - *screen_start = (uint8_t*)(PROG_END); - return 0; -} - -/* int32_t set_handler (int32_t signum, void* handler_address) - * Inputs: int32_t signum, void* handler_address - * Outputs: 0 - success - * Functionality: set handler - */ -int32_t set_handler (int32_t signum, void* handler_address){ - return -1; -} - -/* int32_t sigreturn (void) - * Inputs: none - * Outputs: 0 - success - * Functionality: return from sig - */ -int32_t sigreturn (void){ - return -1; -} diff --git a/mp3-LOS/student-distrib/system_calls.h b/mp3-LOS/student-distrib/system_calls.h deleted file mode 100644 index 30b69bc..0000000 --- a/mp3-LOS/student-distrib/system_calls.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef SYSTEM_CALLS_H -#define SYSTEM_CALLS_H - -#include "lib.h" -#include "terminal_driver.h" -#include "keyboard.h" -#include "rtc.h" -#include "filesys.h" -#include "paging.h" -#include "x86_desc.h" -#include "exceptions_linkage.h" - -#define MAX_PCB_FILES 8 -#define NUM_CHARS 128 -#define SIZE_TASK (SIZE_8KB) - -#define MAX_SHELL 3 -#define MAX_PROCESS 6 - -extern inode_t* inodes; -/* file operations ptr to corresponding functions */ -typedef int32_t (*read_ptr)(int32_t, void*, int32_t); -typedef int32_t (*write_ptr)(int32_t, const void*, int32_t); -typedef int32_t (*open_ptr)(const uint8_t*); -typedef int32_t (*close_ptr)(int32_t); - -typedef struct file_ops_jumptable { // The file operations jump table - open_ptr open_f; - close_ptr close_f; - read_ptr read_f; - write_ptr write_f; -} file_ops_t; - -typedef struct file_desc { // file descriptor - file_ops_t file_ops_ptr; // file operations table pointer - uint32_t inode; // index node: the inode number for this file. This is only valid for data files, and should be 0 for directories and the RTC device file - int32_t file_pos; // file position: A “file position” member that keeps track of where the user is currently reading from in the file. Every read system call should update this member. - int32_t flags; // A “flags” member for, among other things, marking this file descriptor as “in-use.” 0 - not, 1 - in use -} file_desc_t; - - -typedef struct pcb { // Process Control Block - file_desc_t file_descs[MAX_PCB_FILES]; - int8_t args[NUM_CHARS + 1]; // Consider '\0', so +1 - uint32_t esp; - uint32_t ebp; - uint32_t esp_s; // for scheduler - uint32_t ebp_s; // for scheduler - int32_t parent_pid; - int32_t curr_pid; - int32_t pid_in_t; - // pcb_t* parent; -} pcb_t; - -extern int32_t halt (uint8_t status); -extern int32_t execute (const uint8_t* command); -extern int32_t read (int32_t fd, void* buf, int32_t nbytes); -extern int32_t write (int32_t fd, const void* buf, int32_t nbytes); -extern int32_t open (const uint8_t* filename); -extern int32_t close (int32_t fd); -extern int32_t getargs (uint8_t* buf, int32_t nbytes); -extern int32_t vidmap (uint8_t** screen_start); -extern int32_t set_handler (int32_t signum, void* handler_address); -extern int32_t sigreturn (void); -void pid_init(); -extern uint8_t vid_tid; -extern uint8_t curr_schedule; -int32_t pids[MAX_PROCESS]; -int32_t tid_pids[MAX_SHELL][MAX_PROCESS]; - -#endif diff --git a/mp3-LOS/student-distrib/terminal_driver.c b/mp3-LOS/student-distrib/terminal_driver.c deleted file mode 100644 index 31dc97c..0000000 --- a/mp3-LOS/student-distrib/terminal_driver.c +++ /dev/null @@ -1,293 +0,0 @@ -#include "terminal_driver.h" - -#define NUM_CHARS 128 -int of_flag = 0; -int t1_flag = 0; -int t2_flag = 0; -extern uint8_t curr_tid; -typedef struct { - char keys[NUM_CHARS]; - uint8_t first; - uint8_t last; -} key_buffer_t; - -// typedef struct { -// char keys[NUM_CHARS]; -// uint8_t first; -// uint8_t last; -// uint8_t count; // Track number of elements in the buffer -// } key_buffer_t; -key_buffer_t key_buffer; - -// extern struct key_buffer_t* key_buffer; - -/* - * terminal_open - * Opens the terminal and clears the keyboard bugger - * Inputs: None - * Outputs: 0 - * Side Effects: Initializes terminal - * Coverage: - * Files: terminal_driver.c./h - */ -int terminal_open() { - - key_buffer_clear(); - return 0; -} - -/* - * terminal_close - * Closes the terminal - * Inputs: None - * Outputs: 0 - * Side Effects: Closes the terminal and returns 0 - * Coverage: - * Files: terminal_driver.c./h - */ -int terminal_close() { - return 0; -} - -/* - * terminal_write - * Write to the terminal by reading from the buffer - * Inputs: None - * Outputs: n - - * Side Effects: Closes the terminal and returns 0 - * Coverage: - * Files: terminal_driver.c./h - */ -int terminal_write(int fd, char* buf, int n) { - int i; - cli(); - for (i = 0; i < n; i++) { - if (buf[i] != (char) 0) putc(buf[i]); - // else break; - } - sti(); - - return i; -} - -/* - * terminal_read - * Reads from the keyboard buffer into the terminal buffer - * Inputs: None - * Outputs: c - bytes read - * Side Effects: Writes into the terminal buffer - * Coverage: - * Files: terminal_driver.c./h - */ -int terminal_read(int fd, char* buf, int n) { - int i; - - key_buffer_clear(); - // char *cmd = "pingpong\n"; - // for(i= 0; i < 9; i++) key_buffer.keys[i] = cmd[i]; - // key_buffer.last = 9; - // char *cmd = "fish\n"; - // for(i= 0; i < 5; i++) key_buffer.keys[i] = cmd[i]; - // key_buffer.last = 5; - //Wait until a command has been entered - // char *cmd = "fish\n"; - // for(i= 0; i < 5; i++) key_buffer.keys[i] = cmd[i]; - // key_buffer.last = 5; - - while(1) if (key_buffer.keys[key_buffer.last - 1] == '\n') break; - if (strncmp((int8_t*)key_buffer.keys,(int8_t*)"clear",5) == 0) { - clear(); - key_buffer_clear(); - } - //Copy KBD buffer into passed buffer - for (i = 0; i < key_buffer.last; i++) { - if (i == n - 1) break; //Only read up to n characters - buf[i] = key_buffer.keys[i]; - - } - key_buffer_clear(); - return i; -} - -/* - * key_buffer_push - * Push into the keyboard buffer - * Inputs: None - * Outputs: 0 - success - * -1 - fail - * Side Effects: Writes into the keyboard buffer - * Coverage: - * Files: terminal_driver.c./h - */ -int key_buffer_push(char c) { - //OVERFLOW CHECK - if (of_flag == 0) { - if (key_buffer.last == NUM_CHARS) { - of_flag = 1; - // key_buffer.last--; - // printf("KEYBOARD BUFFER OVERFLOW! Clearing Buffer...\n"); - // key_buffer_clear(); - return -1; - } - - //No Overflow, add character to KBD buffer - else { - putc(c); - if(c == ASCII_BACKSPACE){ - if (key_buffer.last == 0) return 0; - key_buffer.last--; - key_buffer.keys[key_buffer.last] = '\0'; - } - else { - key_buffer.keys[key_buffer.last] = c; - key_buffer.last++; - } - } - } else { - if(c == ASCII_BACKSPACE) { - putc(c); - if (key_buffer.last == 0) return 0; - key_buffer.last--; - key_buffer.keys[key_buffer.last] = '\0'; - of_flag = 0; - } - else if (c == ASCII_ENTER) { - putc(c); - key_buffer.last--; - key_buffer.keys[key_buffer.last] = c; - key_buffer.last++; - of_flag = 0; - } - } - return 0; -} - - -/* - * key_buffer_clear - * Clears the keyboard buffer - * Inputs: None - * Outputs: None - * Side Effects: Removes all values from the keyboard buffer - * Coverage: - * Files: terminal_driver.c./h - */ -void key_buffer_clear() { - int i; - for (i = 0; i < NUM_CHARS; i++) {key_buffer.keys[i] = '\0';} - key_buffer.last = 0; -} - -// terminal bad func open -int32_t terminal_bad_open(const uint8_t* filename) { - return -1; -} -// terminal bad func close -int32_t terminal_bad_close(int32_t fd) { - return -1; -} -// terminal bad func read -int32_t terminal_bad_read(int32_t fd, void* buf, int32_t nbyte){ - return -1; -} -// terminal bad func write -int32_t terminal_bad_write(int32_t fd, const void* buf, int32_t nbyte){ - return -1; -} - -/* - * terminal_switch - * switch terminal by terminal id (tid) - * Inputs: tid - * Outputs: None - * Side Effects: switch to new terminal, reserve old - */ -void terminal_switch(uint8_t tid){ - - if(tid >= MAX_TERMINAL || tid == curr_tid) return; - - - register uint32_t ebp_value asm("ebp"); - register uint32_t esp_value asm("esp"); - uint32_t cur_pid = (SIZE_8MB - esp_value) / SIZE_8KB; - pcb_t* cur_pcb = (pcb_t*)(SIZE_8MB - (cur_pid + 1) * SIZE_8KB); - pcb_t* next_pcb; - cur_pcb->ebp_s = ebp_value; - - memcpy((void*)terminal_pages[curr_tid],(void*)VIDEO_ADDR, SIZE_4KB); - memcpy((void*)VIDEO_ADDR, (void*)terminal_pages[tid], SIZE_4KB); - - curr_tid = tid; - - // if (terminals[curr_tid].screen_x == 0 && terminals[curr_tid].screen_y == 0) printf("====== TERMINAL %d ======\n391OS> ", curr_tid); - update_cursor(terminals[curr_tid].cursor_x, terminals[curr_tid].cursor_y); - int i; - - if(tid == 1 && t1_flag == 0){ - t1_flag = 1; - for (i = 0; i < NUM_ROWS; i++) printf("\n"); - terminals[tid].screen_x = 0; - terminals[tid].screen_y = 0; - terminals[tid].cursor_x = 0; - terminals[tid].cursor_y = 0; - execute((uint8_t*)"shell"); - - } - - if(tid == 2 && t2_flag == 0){ - t2_flag = 1; - for (i = 0; i < NUM_ROWS; i++) printf("\n"); - terminals[tid].screen_x = 0; - terminals[tid].screen_y = 0; - terminals[tid].cursor_x = 0; - terminals[tid].cursor_y = 0; - execute((uint8_t*)"shell"); - - } - - int32_t next_pid; - int j; - for (j = 0; j < MAX_PROCESS; j++) { - if (tid_pids[curr_tid][j] == -1) - break; - } - next_pid = tid_pids[curr_tid][j-1]; - - - next_pcb = (pcb_t*)(SIZE_8MB - (next_pid+ 1) * SIZE_8KB); - - // map virtual program image (128MB) to physical user program (shell# 8MB-12MB-16MB) - SET_PDE(page_dir, PROG_START/SIZE_4MB, 1, 1, 0, (SIZE_8MB + (next_pid * SIZE_4MB)) / SIZE_4KB); - - /* Flush TLB */ - flush_tlb(page_dir); - // Write Parent Process Info Back into TSS - tss.ss0 = KERNEL_DS; - tss.esp0 = (uint32_t)(SIZE_8MB - (next_pid) * SIZE_TASK) - 4; - asm volatile(" \n\ - movl %0, %%ebp \n\ - leave \n\ - ret" - : /* no output */ - : "r" (next_pcb->ebp_s) - :"ebp"); -} -/* - * terminal_init - * initialize the terminal struct - * Inputs: None - * Outputs: 0 - * Side Effects: initialize the terminal and returns 0 - */ -int terminal_init() { - int i; - for(i = 0; i < MAX_TERMINAL; i++) { - terminals[i].tid = i; - terminals[i].screen_x = 0; - terminals[i].screen_y = 0; - terminals[i].cursor_x = 0; - terminals[i].cursor_y = 1; - } - - return 0; -} diff --git a/mp3-LOS/student-distrib/terminal_driver.h b/mp3-LOS/student-distrib/terminal_driver.h deleted file mode 100644 index ddee987..0000000 --- a/mp3-LOS/student-distrib/terminal_driver.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _TERMINAL_DRIVER_H -#define _TERMINAL_DRIVER_H - -#include "types.h" -#include "keyboard.h" -#include "lib.h" -#include "system_calls.h" -#include "paging.h" -#include "scheduler.h" - -#define MAX_TERMINAL 3 -#define MAX_CHARS 128 -#define NUM_IN_PAGE 1024 -#define NUM_COLS 80 -#define NUM_ROWS 25 - -typedef struct terminal_desc { - int screen_x; - int screen_y; - int cursor_x; - int cursor_y; - int tid; -} terminal_desc_t; - -terminal_desc_t terminals[MAX_TERMINAL]; -uint8_t terminal_pages[MAX_TERMINAL][4096]; - -int terminal_init(); // checkpoint 5 -int terminal_open(); -int terminal_close(); -int terminal_write(int fd, char* buf, int n); -int terminal_read(int fd, char* buf, int n); -int key_buffer_push(char c); -void key_buffer_clear(); - -// terminal bad func -int32_t terminal_bad_open(const uint8_t* filename); -int32_t terminal_bad_close(int32_t fd); -int32_t terminal_bad_read(int32_t fd, void* buf, int32_t nbyte); -int32_t terminal_bad_write(int32_t fd, const void* buf, int32_t nbyte); - -// terminal switch -void terminal_switch(uint8_t tid); -extern int of_flag; -// extern int t1_flag; -// extern int t2_flag; - -#endif diff --git a/mp3-LOS/student-distrib/tests.c b/mp3-LOS/student-distrib/tests.c deleted file mode 100644 index 2158710..0000000 --- a/mp3-LOS/student-distrib/tests.c +++ /dev/null @@ -1,507 +0,0 @@ -#include "tests.h" -#include "x86_desc.h" -#include "lib.h" -#include "rtc.h" -#include "filesys.h" -#include "terminal_driver.h" -#include "keyboard.h" - -#define PASS 1 -#define FAIL 0 - -/* format these macros as you see fit */ -#define TEST_HEADER \ - printf("[TEST %s] Running %s at %s:%d\n", __FUNCTION__, __FUNCTION__, __FILE__, __LINE__) -#define TEST_OUTPUT(name, result) \ - printf("[TEST %s] Result = %s\n", name, (result) ? "PASS" : "FAIL"); - -static inline void assertion_failure(){ - /* Use exception #15 for assertions, otherwise - reserved by Intel */ - asm volatile("int $15"); -} - - -/* Checkpoint 1 tests */ - -/* IDT Test - Example - * - * Asserts that first 10 IDT entries are not NULL - * Inputs: None - * Outputs: PASS/FAIL - * Side Effects: None - * Coverage: Load IDT, IDT definition - * Files: x86_desc.h/S - */ -int idt_test(){ - TEST_HEADER; - - int i; - int result = PASS; - for (i = 0; i < 10; ++i){ - if ((idt[i].offset_15_00 == NULL) && - (idt[i].offset_31_16 == NULL)){ - assertion_failure(); - result = FAIL; - } - } - - return result; -} - -// add more tests here - - -/* - * divide_error_test - * Assert that div 0 exception can be detected - * Inputs: None - * Outputs: FAIL - * Side Effects: None - * Coverage: divide_error exception, IDT - * Files: idt.c/h - */ -int divide_error_test(){ - TEST_HEADER; - - int a = 0; - int b; - b = 1 / a; - - return FAIL; -} - -/* - * paging_test - * return PASS if successfully dereference all - * Inputs: None - * Outputs: PASS - * Side Effects: None - * Coverage: paging - * Files: idt.c/h - */ -int paging_test() { - TEST_HEADER; - unsigned char* video_addr = (unsigned char*) 0xB8000; - unsigned char* video_addr_end = video_addr + 0x1000; - unsigned char* k_addr = (unsigned char*) 0x400000; - unsigned char* k_addr_end = (unsigned char*) 0x800000; - unsigned char* addr; - unsigned char test; - - - for (addr = video_addr; addr < video_addr_end; addr++) - test = (*addr); - - for (addr = k_addr; addr < k_addr_end; addr++) - test = (*addr); - - return PASS; -} - -/* - * breakpoint_test - * Check if breakpoint exception can successfully occur - * Inputs: None - * Outputs: FAIL - * Side Effects: None - * Coverage: breakpoint exception, IDT - * Files: idt.c/h - */ -int breakpoint_test(){ - TEST_HEADER; - asm("int $3"); - return FAIL; -} - -// /* -// * overflow_test -// * Check if overflow exception can successfully occur -// * Inputs: None -// * Outputs: FAIL -// * Side Effects: None -// * Coverage: overflow exception, IDT -// * Files: idt.c/h -// */ -// int overflow_test(){ -// -// return FAIL; -// } - -// /* -// * bound_test -// * Check if bound range exceeded exception can successfully occur -// * Inputs: None -// * Outputs: FAIL -// * Side Effects: None -// * Coverage: bound range exceeded exception, IDT -// * Files: idt.c/h -// */ -// int bound_test(){ -// asm("bound"); -// return FAIL; -// } - -int sim_test(){ - TEST_HEADER; - float a, b; - a = 0.0; - b= 1.23; - - b = b / a; - - return FAIL; -} - -int machine_test() { - TEST_HEADER; - - asm("int $18"); - - return FAIL; -} - -int missalignment_test() { - - TEST_HEADER; - - asm("int $17"); - - return FAIL; - -} - -int FPU_test() { - TEST_HEADER; - - asm("int $16"); - - return FAIL; -} - -// int Gen_Prot_test() { -// TEST_HEADER; - -// int("into"); - -// return FAIL; -// } - -int Stack_Seg_test() { - TEST_HEADER; - - asm("int $12"); - - return FAIL; -} - -int Seg_NP() { - TEST_HEADER; - - asm("int $11"); - - return FAIL; -} - -/* Checkpoint 2 tests */ -int Terminal_Write_Test() { - TEST_HEADER; - char* buffer; - - buffer = "Hello World\n"; - printf("Printing Hello World with terminal write...\n"); - // terminal_write(0, buffer, 11); - - if (terminal_write(0, buffer, 11) != 11) return FAIL; - if (terminal_write(0, buffer, 12) != 11) return FAIL; - if (terminal_write(0, buffer, 5) != 5) return FAIL; - - return PASS; - -} - - -int RTC_TEST(){ - printf("start write test"); - TEST_HEADER; - // uint8_t buf[4]; - int i; - // int x; - - // testing rtc_open - printf("\nrtc_open: should print at 2 Hz\n"); - uint8_t* file = NULL; // argument isnt used so initializing to NULL - rtc_open(file); - for(i = 0; i < 15; i++){ - while(rtc_read(0,NULL,0) != 1); - putc('1'); - } - printf("\n\n"); - - - // for(i = 0; i < 20; i++){ - // // printf("for %d", i); - // while(rtc_read(0,NULL,0) != 1); - // // while(!(num_interrupts_generated >= num_interrupts_needed)); - // putc('1'); - // } - // printf("\n"); - - printf("rtc_write: should print lines at each possible interrupt rate\n\n"); - uint32_t freq = 4; - printf("4 Hz: "); - rtc_write(0, &freq, 0); - // printf("end write test"); - - for(i = 0; i < 10; i++){ - while(rtc_read(0,NULL,0) != 1); - putc('2'); - } - printf("\n"); - - - freq = 8; - printf("8 Hz: "); - rtc_write(0, &freq, 0); - for( i = 0; i < 20; i++){ - if(rtc_read(0, NULL, 0) == 1); - putc('3'); - } - printf("\n"); - - - freq = 16; - printf("16 Hz: "); - rtc_write(0, &freq, 0) ; - for( i = 0; i < 30; i++){ - if(rtc_read(0, NULL, 0) == 1); - putc('4'); - } - printf("\n"); - - - freq = 32; - printf("32 Hz: "); - rtc_write(0, &freq, 0) ; - for( i = 0; i < 40; i++){ - if(rtc_read(0, NULL, 0) == 1); - putc('5'); - } - printf("\n"); - - - freq = 64; - printf("64 Hz: "); - rtc_write(0, &freq, 0) ; - for( i = 0; i < 50; i++){ - if(rtc_read(0, NULL, 0) == 1); - putc('6'); - } - printf("\n"); - - - freq = 128; - printf("128 Hz: "); - rtc_write(0, &freq, 0) ; - for( i = 0; i < 60; i++){ - if(rtc_read(0, NULL, 0) == 1); - putc('7'); - } - printf("\n"); - - - freq = 256; - printf("256 Hz: "); - rtc_write(0, &freq, 0) ; - for( i = 0; i < 70; i++){ - if(rtc_read(0, NULL, 0) == 1); - putc('8'); - } - printf("\n"); - - freq = 512; - printf("512 Hz: "); - rtc_write(0, &freq, 0) ; - for( i = 0; i < 72; i++){ - if(rtc_read(0, NULL, 0) == 1); - putc('9'); - } - printf("\n"); - - freq = 1024; - printf("1024 Hz: "); - rtc_write(0, &freq, 0) ; - for( i = 0; i < 71; i++){ - if(rtc_read(0, NULL, 0) == 1); - putc('0'); - } - printf("\n"); - - return PASS; - -} - - - -/* - * open_file_test - * return PASS if buffer file - * Inputs: None - * Outputs: PASS - * Side Effects: None - * Coverage: file system - * Files: filesys.c/h - */ -int open_file_test() { - if(fopen((uint8_t*)"ls") == 0) return PASS; - return FAIL; -} -/* - * close_file_test - * return PASS if buffer file - * Inputs: None - * Outputs: PASS - * Side Effects: None - * Coverage: file system - * Files: filesys.c/h - */ -int close_file_test() { - int32_t fd; - if(fclose(fd) == 0) return PASS; - return FAIL; -} - - -/* - * read_file_test - * return PASS if buffer file - * Inputs: None - * Outputs: PASS - * Side Effects: None - * Coverage: file system - * Files: filesys.c/h - */ -int read_file_test(){ - - TEST_HEADER; - int i = 0; - uint32_t len = 40960; - uint8_t buf[40960]; - // uint8_t* fname = (uint8_t*)"frame0.txt"; - // uint8_t* fname = (uint8_t*)"frame1.txt"; - //uint8_t* fname = (uint8_t*)"grep"; - // uint8_t* fname = (uint8_t*)"ls"; - uint8_t* fname = (uint8_t*)"verylargetextwithverylongname.tx"; - if (read_file_by_name(fname, buf, &len)) - - clear(); - for (i = 0; i < len; i++) { - //printf("%c",buf[i]); // works for \0 - putc(buf[i]); - } - // puts((int8_t*)buf); - printf("\n"); - printf("file_name: "); - puts((int8_t*)fname); - printf("\n"); - return PASS; - return FAIL; - -} - - -/* - * read_directory_test - * return PASS if read dir - * Inputs: None - * Outputs: PASS - * Side Effects: None - * Coverage: file system - * Files: filesys.c/h - */ -int read_directory_test(){ - TEST_HEADER; - int i,j; - - uint8_t buf[33]; - - // 63 is the max directory number in filesystem - printf("\n"); - for (i = 0; i < 63; i++){ - int count = 0; - int temp = 0; - uint32_t ftype; - uint32_t fsize; - if (read_directory(buf, i, &ftype, &fsize) == -1) - break; - printf("file_name:"); - buf[32] = '\0'; // indicate an end - printf((int8_t*)buf); - temp = fsize; - while (temp / 10) - { - count++; - temp /= 10; - } - // output entry - printf(", file_type:%d, file_size:", ftype); - count = 7 - count; // align - for (j = 0; j < count; j++) printf(" "); - printf("%d", fsize); - printf("\n"); - } - return PASS; -} - - -// int Terminal_Write_Incorrect_Bits() { -// TEST_HEADER; -// char* buffer; -// buffer = "hello"; -// terminal_open(); -// if (Terminal_Write(0, buffer, 99999) != 5) return FAIL; -// if (Terminal_Write(0, buffer, 1) != 1) return FAIL; -// terminal_close(); - -// return PASS; -// } - -/* Checkpoint 3 tests */ -/* Checkpoint 4 tests */ -/* Checkpoint 5 tests */ - - -/* Test suite entry point */ -void launch_tests(){ - // TEST_OUTPUT("idt_test", idt_test()); - // launch your tests here - // TEST_OUTPUT("divide_error_test", divide_error_test()); - // TEST_OUTPUT("paging_test", paging_test()); - // TEST_OUTPUT("breakpoint_test", breakpoint_test()); - //TEST_OUTPUT("overflow_test", overflow_test()); - // TEST_OUTPUT("bound_test", bound_test()); - // TEST_OUTPUT("Seg_NP_test", Seg_NP()); - // TEST_OUTPUT("SIM TEST", sim_test()); - // TEST_OUTPUT("Machine Test", machine_test()); - // TEST_OUTPUT("Misallighment Test", missalignment_test()); - // TEST_OUTPUT("FPU Test", FPU_test()); - // TEST_OUTPUT("Protection", Gen_Prot_test()); - // TEST_OUTPUT("Stack Segment Test", Stack_Seg_test()); - // TEST_OUTPUT("Segment Not presnt", Seg_NP()); - - //-----------CHECKPOINT 2------------// - //// TEST_OUTPUT("Terminal Write Incorrect Bits Test", Terminal_Write_Incorrect_Bits()); - - /* Checkpoint 2 tests */ - - //TEST_OUTPUT("open file test", open_file_test()); - //TEST_OUTPUT("close file test", close_file_test()); - TEST_OUTPUT("read file test", read_file_test()); - // TEST_OUTPUT("read directory test", read_directory_test()); - - - - // TEST_OUTPUT("rtc test", RTC_TEST()); - // TEST_OUTPUT("Basic Terminal Write", Terminal_Write_Test()); - -} diff --git a/mp3-LOS/student-distrib/tests.h b/mp3-LOS/student-distrib/tests.h deleted file mode 100644 index c004e22..0000000 --- a/mp3-LOS/student-distrib/tests.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef TESTS_H -#define TESTS_H - -// test launcher -void launch_tests(); - -#endif /* TESTS_H */ diff --git a/mp3-LOS/student-distrib/types.h b/mp3-LOS/student-distrib/types.h deleted file mode 100644 index 0c9fff0..0000000 --- a/mp3-LOS/student-distrib/types.h +++ /dev/null @@ -1,26 +0,0 @@ -/* types.h - Defines to use the familiar explicitly-sized types in this - * OS (uint32_t, int8_t, etc.). This is necessary because we don't want - * to include when building this OS - * vim:ts=4 noexpandtab - */ - -#ifndef _TYPES_H -#define _TYPES_H - -#define NULL 0 - -#ifndef ASM - -/* Types defined here just like in */ -typedef int int32_t; -typedef unsigned int uint32_t; - -typedef short int16_t; -typedef unsigned short uint16_t; - -typedef char int8_t; -typedef unsigned char uint8_t; - -#endif /* ASM */ - -#endif /* _TYPES_H */ diff --git a/mp3-LOS/student-distrib/x86_desc.S b/mp3-LOS/student-distrib/x86_desc.S deleted file mode 100644 index aedb458..0000000 --- a/mp3-LOS/student-distrib/x86_desc.S +++ /dev/null @@ -1,116 +0,0 @@ -# x86_desc.S - Set up x86 segment descriptors, descriptor tables -# vim:ts=4 noexpandtab - -#define ASM 1 -#include "x86_desc.h" - -.text - -.globl ldt_size, tss_size, gdt_size -.globl gdt_desc, ldt_desc, tss_desc -.globl tss, tss_desc_ptr, ldt, ldt_desc_ptr -.globl gdt_ptr -.globl idt_desc_ptr, idt - -.align 4 - -gdt_size: - .long gdt_bottom - gdt - 1 - -tss_size: - .long tss_bottom - tss - 1 - -ldt_size: - .long ldt_bottom - ldt - 1 - - .word 0 # Padding -ldt_desc: - .word KERNEL_LDT - .long ldt - - .align 4 -tss: -_tss: - .rept 104 - .byte 0 - .endr -tss_bottom: - - .align 16 -gdt: -_gdt: - - # First GDT entry cannot be used - .quad 0 - - # NULL entry - .quad 0 - - # Segmentation will not be used - # CS and DS both are 0-4GB r/w segments - # - # The layout is (from Intel IA-32 reference manual): - # 31 24 23 22 21 20 19 16 15 14 13 12 11 8 7 0 - # |----------------------------------------------------------------------| - # | | | D | | A | Seg | | D | | | | - # | Base 31:24 | G | / | 0 | V | Limit | P | P | S | Type | Base 23:16 | - # | | | B | | L | 19:16 | | L | | | | - # |----------------------------------------------------------------------| - # - # |----------------------------------------------------------------------| - # | | | - # | Base 15:0 | Segment Limit 15:0 | - # | | | - # |----------------------------------------------------------------------| - -gdt_ptr: - # Set up an entry for kernel CS - .quad 0x00CF9A000000FFFF - - # Set up an entry for kernel DS - .quad 0x00CF92000000FFFF - - # Set up an entry for user CS - .quad 0x00CFFA000000FFFF - - # Set up an entry for user DS - .quad 0x00CFF2000000FFFF - - # Set up an entry for TSS -tss_desc_ptr: - .quad 0 - - # Set up one LDT -ldt_desc_ptr: - .quad 0 - -gdt_bottom: - - .align 16 -ldt: - .rept 4 - .quad 0 - .endr -ldt_bottom: - -.align 4 - .word 0 # Padding - -gdt_desc: - .word gdt_bottom - gdt - 1 - .long gdt - - .align 16 -idt_desc_ptr: - .word idt_bottom - idt - 1 - .long idt - - - .align 16 -idt: -_idt: - .rept NUM_VEC - .quad 0 - .endr - -idt_bottom: diff --git a/mp3-LOS/student-distrib/x86_desc.h b/mp3-LOS/student-distrib/x86_desc.h deleted file mode 100644 index 5d37fcd..0000000 --- a/mp3-LOS/student-distrib/x86_desc.h +++ /dev/null @@ -1,220 +0,0 @@ -/* x86_desc.h - Defines for various x86 descriptors, descriptor tables, - * and selectors - * vim:ts=4 noexpandtab - */ - -#ifndef _X86_DESC_H -#define _X86_DESC_H - -#include "types.h" - -/* Segment selector values */ -#define KERNEL_CS 0x0010 -#define KERNEL_DS 0x0018 -#define USER_CS 0x0023 -#define USER_DS 0x002B -#define KERNEL_TSS 0x0030 -#define KERNEL_LDT 0x0038 - -/* Size of the task state segment (TSS) */ -#define TSS_SIZE 104 - -/* Number of vectors in the interrupt descriptor table (IDT) */ -#define NUM_VEC 256 - -#ifndef ASM - -/* This structure is used to load descriptor base registers - * like the GDTR and IDTR */ -typedef struct x86_desc { - uint16_t padding; - uint16_t size; - uint32_t addr; -} x86_desc_t; - -/* This is a segment descriptor. It goes in the GDT. */ -typedef struct seg_desc { - union { - uint32_t val[2]; - struct { - uint16_t seg_lim_15_00; - uint16_t base_15_00; - uint8_t base_23_16; - uint32_t type : 4; - uint32_t sys : 1; - uint32_t dpl : 2; - uint32_t present : 1; - uint32_t seg_lim_19_16 : 4; - uint32_t avail : 1; - uint32_t reserved : 1; - uint32_t opsize : 1; - uint32_t granularity : 1; - uint8_t base_31_24; - } __attribute__ ((packed)); - }; -} seg_desc_t; - -/* TSS structure */ -typedef struct __attribute__((packed)) tss_t { - uint16_t prev_task_link; - uint16_t prev_task_link_pad; - - uint32_t esp0; - uint16_t ss0; - uint16_t ss0_pad; - - uint32_t esp1; - uint16_t ss1; - uint16_t ss1_pad; - - uint32_t esp2; - uint16_t ss2; - uint16_t ss2_pad; - - uint32_t cr3; - - uint32_t eip; - uint32_t eflags; - - uint32_t eax; - uint32_t ecx; - uint32_t edx; - uint32_t ebx; - uint32_t esp; - uint32_t ebp; - uint32_t esi; - uint32_t edi; - - uint16_t es; - uint16_t es_pad; - - uint16_t cs; - uint16_t cs_pad; - - uint16_t ss; - uint16_t ss_pad; - - uint16_t ds; - uint16_t ds_pad; - - uint16_t fs; - uint16_t fs_pad; - - uint16_t gs; - uint16_t gs_pad; - - uint16_t ldt_segment_selector; - uint16_t ldt_pad; - - uint16_t debug_trap : 1; - uint16_t io_pad : 15; - uint16_t io_base_addr; -} tss_t; - -/* Some external descriptors declared in .S files */ -extern x86_desc_t gdt_desc; - -extern uint16_t ldt_desc; -extern uint32_t ldt_size; -extern seg_desc_t ldt_desc_ptr; -extern seg_desc_t gdt_ptr; -extern uint32_t ldt; - -extern uint32_t tss_size; -extern seg_desc_t tss_desc_ptr; -extern tss_t tss; - -/* Sets runtime-settable parameters in the GDT entry for the LDT */ -#define SET_LDT_PARAMS(str, addr, lim) \ -do { \ - str.base_31_24 = ((uint32_t)(addr) & 0xFF000000) >> 24; \ - str.base_23_16 = ((uint32_t)(addr) & 0x00FF0000) >> 16; \ - str.base_15_00 = (uint32_t)(addr) & 0x0000FFFF; \ - str.seg_lim_19_16 = ((lim) & 0x000F0000) >> 16; \ - str.seg_lim_15_00 = (lim) & 0x0000FFFF; \ -} while (0) - -/* Sets runtime parameters for the TSS */ -#define SET_TSS_PARAMS(str, addr, lim) \ -do { \ - str.base_31_24 = ((uint32_t)(addr) & 0xFF000000) >> 24; \ - str.base_23_16 = ((uint32_t)(addr) & 0x00FF0000) >> 16; \ - str.base_15_00 = (uint32_t)(addr) & 0x0000FFFF; \ - str.seg_lim_19_16 = ((lim) & 0x000F0000) >> 16; \ - str.seg_lim_15_00 = (lim) & 0x0000FFFF; \ -} while (0) - -/* An interrupt descriptor entry (goes into the IDT) */ -typedef union idt_desc_t { - uint32_t val[2]; - struct { - uint16_t offset_15_00; - uint16_t seg_selector; - uint8_t reserved4; - uint32_t reserved3 : 1; - uint32_t reserved2 : 1; - uint32_t reserved1 : 1; - uint32_t size : 1; - uint32_t reserved0 : 1; - uint32_t dpl : 2; - uint32_t present : 1; - uint16_t offset_31_16; - } __attribute__ ((packed)); -} idt_desc_t; - -/* The IDT itself (declared in x86_desc.S */ -extern idt_desc_t idt[NUM_VEC]; -/* The descriptor used to load the IDTR */ -extern x86_desc_t idt_desc_ptr; - -/* Sets runtime parameters for an IDT entry */ -#define SET_IDT_ENTRY(str, handler) \ -do { \ - str.offset_31_16 = ((uint32_t)(handler) & 0xFFFF0000) >> 16; \ - str.offset_15_00 = ((uint32_t)(handler) & 0xFFFF); \ - str.present = 1; \ -} while (0) - -/* Load task register. This macro takes a 16-bit index into the GDT, - * which points to the TSS entry. x86 then reads the GDT's TSS - * descriptor and loads the base address specified in that descriptor - * into the task register */ -#define ltr(desc) \ -do { \ - asm volatile ("ltr %w0" \ - : \ - : "r" (desc) \ - : "memory", "cc" \ - ); \ -} while (0) - -/* Load the interrupt descriptor table (IDT). This macro takes a 32-bit - * address which points to a 6-byte structure. The 6-byte structure - * (defined as "struct x86_desc" above) contains a 2-byte size field - * specifying the size of the IDT, and a 4-byte address field specifying - * the base address of the IDT. */ -#define lidt(desc) \ -do { \ - asm volatile ("lidt (%0)" \ - : \ - : "g" (desc) \ - : "memory" \ - ); \ -} while (0) - -/* Load the local descriptor table (LDT) register. This macro takes a - * 16-bit index into the GDT, which points to the LDT entry. x86 then - * reads the GDT's LDT descriptor and loads the base address specified - * in that descriptor into the LDT register */ -#define lldt(desc) \ -do { \ - asm volatile ("lldt %%ax" \ - : \ - : "a" (desc) \ - : "memory" \ - ); \ -} while (0) - -#endif /* ASM */ - -#endif /* _x86_DESC_H */ diff --git a/mp3-LOS/syscalls/Makefile b/mp3-LOS/syscalls/Makefile deleted file mode 100644 index e59b153..0000000 --- a/mp3-LOS/syscalls/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -CFLAGS += -Wall -nostdlib -ffreestanding -LDFLAGS += -nostdlib -ffreestanding -CC = gcc - -ALL: cat grep hello ls pingpong counter shell sigtest testprint syserr - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -%.o: %.S - $(CC) $(CFLAGS) -c -Wall -o $@ $< - -%.exe: ece391%.o ece391syscall.o ece391support.o - $(CC) $(LDFLAGS) -o $@ $^ - -%: %.exe - ../elfconvert $< - mv $<.converted to_fsdir/$@ - -clean:: - rm -f *~ *.o - -clear: clean - rm -f *.converted - rm -f *.exe - rm -f to_fsdir/* diff --git a/mp3-LOS/syscalls/ece391cat.c b/mp3-LOS/syscalls/ece391cat.c deleted file mode 100644 index 56fdf69..0000000 --- a/mp3-LOS/syscalls/ece391cat.c +++ /dev/null @@ -1,32 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -int main () -{ - int32_t fd, cnt; - uint8_t buf[1024]; - - if (0 != ece391_getargs (buf, 1024)) { - ece391_fdputs (1, (uint8_t*)"could not read arguments\n"); - return 3; - } - - if (-1 == (fd = ece391_open (buf))) { - ece391_fdputs (1, (uint8_t*)"file not found\n"); - return 2; - } - - while (0 != (cnt = ece391_read (fd, buf, 1024))) { - if (-1 == cnt) { - ece391_fdputs (1, (uint8_t*)"file read failed\n"); - return 3; - } - if (-1 == ece391_write (1, buf, cnt)) - return 3; - } - - return 0; -} - diff --git a/mp3-LOS/syscalls/ece391counter.c b/mp3-LOS/syscalls/ece391counter.c deleted file mode 100644 index 8933439..0000000 --- a/mp3-LOS/syscalls/ece391counter.c +++ /dev/null @@ -1,45 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -#define BUFSIZE 1024 - -int main () -{ - uint32_t i, cnt, max = 0; - uint8_t buf[BUFSIZE]; - - ece391_fdputs(1, (uint8_t*)"Enter the Test Number: (0): 100, (1): 10000, (2): 100000\n"); - if (-1 == (cnt = ece391_read(0, buf, BUFSIZE-1)) ) { - ece391_fdputs(1, (uint8_t*)"Can't read the number from keyboard.\n"); - return 3; - } - buf[cnt] = '\0'; - - if ((ece391_strlen(buf) > 2) || ((ece391_strlen(buf) == 2) && ((buf[0] < '0') || (buf[0] > '2')))) { - ece391_fdputs(1, (uint8_t*)"Wrong Choice!\n"); - return 0; - } else { - switch (buf[0]) { - case '0': - max = 100; - break; - case '1': - max = 10000; - break; - case '2': - max = 100000; - break; - } - } - - for (i = 0; i < max; i++) { - ece391_itoa(i+1, buf, 10); - ece391_fdputs(1, buf); - ece391_fdputs(1, (uint8_t*)"\n"); - } - - return 0; -} - diff --git a/mp3-LOS/syscalls/ece391emulate.c b/mp3-LOS/syscalls/ece391emulate.c deleted file mode 100644 index 76a422a..0000000 --- a/mp3-LOS/syscalls/ece391emulate.c +++ /dev/null @@ -1,227 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "ece391support.h" -#include "ece391syscall.h" -#include "ece391sysnum.h" - - -static uint32_t start_esp; -static int32_t dir_fd = -1; -static DIR* dir = NULL; - - -/* - * (copied from the real system call support) - * - * Rather than create a case for each number of arguments, we simplify - * and use one macro for up to three arguments; the system calls should - * ignore the other registers, and they're caller-saved anyway. - */ -#define DO_CALL(name,number) \ -asm volatile (" \ -.GLOBL " #name " ;\ -" #name ": ;\ - PUSHL %EBX ;\ - MOVL $" #number ",%EAX ;\ - MOVL 8(%ESP),%EBX ;\ - MOVL 12(%ESP),%ECX ;\ - MOVL 16(%ESP),%EDX ;\ - INT $0x80 ;\ - CMP $0xFFFFC000,%EAX ;\ - JBE 1f ;\ - MOVL $-1,%EAX ;\ -1: POPL %EBX ;\ - RET \ -") - -/* these wrappers require no changes */ -extern int32_t __ece391_read (int32_t fd, void* buf, int32_t nbytes); -extern int32_t __ece391_write (int32_t fd, const void* buf, int32_t nbytes); -extern int32_t __ece391_close (int32_t fd); -void fake_function () { -DO_CALL(ece391_halt,1 /* SYS_HALT */); -DO_CALL(__ece391_read,3 /* SYS_READ */); -DO_CALL(__ece391_write,4 /* SYS_WRITE */); -DO_CALL(__ece391_close,6 /* SYS_CLOSE */); - -/* Call the main() function, then halt with its return value. */ - -asm volatile (" \n\ -.GLOBAL _start \n\ -_start: \n\ - MOVL %ESP,start_esp \n\ - CALL main \n\ - PUSHL %EAX \n\ - CALL ece391_halt \n\ -"); - -/* end of fake container function */ -} - -int32_t -ece391_execute (const uint8_t* command) -{ - int status; - uint8_t buf[1026]; - char* args[1024]; - uint8_t* scan; - uint32_t n_arg; - - if (1023 < ece391_strlen (command)) - return -1; - buf[0] = '.'; - buf[1] = '/'; - ece391_strcpy (buf + 2, command); - for (scan = buf + 2; '\0' != *scan && ' ' != *scan && '\n' != *scan; - scan++); - args[0] = (char*)buf; - n_arg = 1; - if ('\0' != *scan) { - *scan++ = '\0'; - /* parse arguments */ - while (1) { - while (' ' == *scan) scan++; - if ('\0' == *scan || '\n' == *scan) { - *scan = '\0'; - break; - } - args[n_arg++] = (char*)scan; - while ('\0' != *scan && ' ' != *scan && '\n' != *scan) scan++; - if ('\0' != *scan) - *scan++ = '\0'; - } - } - args[n_arg] = NULL; - if (0 == fork ()) { - execv ((char*)buf, args); - kill (getpid (), 9); - } - (void)wait (&status); - if (WIFEXITED (status)) - return WEXITSTATUS (status); - if (9 == WTERMSIG (status)) - return -1; - return 256; -} - -int32_t -ece391_open (const uint8_t* filename) -{ - uint32_t rval; - - if (0 == ece391_strcmp (filename, (uint8_t*)".")) { - dir = opendir ("."); - dir_fd = open ("/dev/null", O_RDONLY); - return dir_fd; - } - - asm volatile ("INT $0x80" : "=a" (rval) : - "a" (5), "b" (filename), "c" (O_RDONLY)); - if (rval > 0xFFFFC000) - return -1; - return rval; -} - -int32_t -ece391_getargs (uint8_t* buf, int32_t nbytes) -{ - int32_t argc = *(uint32_t*)start_esp; - uint8_t** argv = (uint8_t**)(start_esp + 4); - int32_t idx, len; - - idx = 1; - while (idx < argc) { - len = ece391_strlen (argv[idx]); - if (len > nbytes) - return -1; - ece391_strcpy (buf, argv[idx]); - buf += len; - nbytes -= len; - if (++idx >= argc) - break; - if (nbytes < 1) - return -1; - *buf++ = ' '; - nbytes--; - } - if (nbytes < 1) - return -1; - *buf = '\0'; - return 0; -} - -int32_t -ece391_vidmap (uint8_t** screen_start) -{ - static int mem_fd = -1; - void* mem_image; - - if(mem_fd == -1) { - mem_fd = open ("/dev/mem", O_RDWR); - } - - if ((mem_image = mmap((void*)0, 1024*1024, PROT_READ | PROT_WRITE, - MAP_SHARED, mem_fd, 0)) == MAP_FAILED) { - perror ("mmap low memory"); - return -1; - } - - *screen_start = (uint8_t*)(mem_image + 0xb8000); - return 0; -} - -int32_t -ece391_read (int32_t fd, void* buf, int32_t nbytes) -{ - struct dirent* de; - int32_t copied; - uint8_t* from; - uint8_t* to; - - if (NULL == dir || dir_fd != fd) - return __ece391_read (fd, buf, nbytes); - if (NULL == (de = readdir (dir))) - return 0; - to = buf; - from = (uint8_t*)de->d_name; - copied = 0; - while ('\0' != *from) { - *to++ = *from++; - if (++copied == nbytes) - return nbytes; - if (32 == copied) - return 32; - } - while (nbytes > copied && 32 > copied) { - *to++ = '\0'; - copied++; - } - return copied; -} - -int32_t -ece391_write (int32_t fd, const void* buf, int32_t nbytes) -{ - if (NULL == dir || dir_fd != fd) - return __ece391_write (fd, buf, nbytes); - return -1; -} - -int32_t -ece391_close (int32_t fd) -{ - if (NULL == dir || dir_fd != fd) - return __ece391_close (fd); - (void)closedir (dir); - dir = NULL; - (void)close (dir_fd); - dir_fd = -1; - return 0; -} - diff --git a/mp3-LOS/syscalls/ece391grep.c b/mp3-LOS/syscalls/ece391grep.c deleted file mode 100644 index 0ab27c4..0000000 --- a/mp3-LOS/syscalls/ece391grep.c +++ /dev/null @@ -1,97 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -#define BUFSIZE 1024 -#define SBUFSIZE 33 - -int32_t -do_one_file (const char* s, const char* fname) -{ - int32_t fd, cnt, last, line_start, line_end, check, s_len; - uint8_t data[BUFSIZE+1]; - - s_len = ece391_strlen ((uint8_t*)s); - if (-1 == (fd = ece391_open ((uint8_t*)fname))) { - ece391_fdputs (1, (uint8_t*)"file open failed\n"); - return -1; - } - last = 0; - while (1) { - cnt = ece391_read (fd, data + last, BUFSIZE - last); - if (-1 == cnt) { - ece391_fdputs (1, (uint8_t*)"file read failed\n"); - return -1; - } - last += cnt; - line_start = 0; - while (1) { - line_end = line_start; - while (line_end < last && '\n' != data[line_end]) - line_end++; - if ('\n' != data[line_end] && 0 != cnt && line_start != 0) { - /* copy from line_start to last down to 0 and fix last */ - data[line_end] = '\0'; - ece391_strcpy (data, data + line_start); - last -= line_start; - break; - } - /* search the line */ - data[line_end] = '\0'; - for (check = line_start; check < line_end; check++) { - if (s[0] == data[check] && - 0 == ece391_strncmp ((uint8_t*)(data + check), (uint8_t*)s, s_len)) { - ece391_fdputs (1, (uint8_t*)fname); - ece391_fdputs (1, (uint8_t*)":"); - ece391_fdputs (1, data + line_start); - ece391_fdputs (1, (uint8_t*)"\n"); - break; - } - } - line_start = line_end + 1; - if (line_start >= last) { - last = 0; - break; - } - } - if (0 == cnt) - break; - } - if (-1 == ece391_close (fd)) { - ece391_fdputs (1, (uint8_t*)"file close failed\n"); - return -1; - } - return 0; -} - -int main () -{ - int32_t fd, cnt; - uint8_t buf[SBUFSIZE]; - uint8_t search[BUFSIZE]; - - if (0 != ece391_getargs (search, BUFSIZE)) { - ece391_fdputs (1, (uint8_t*)"could not read argument\n"); - return 3; - } - - if (-1 == (fd = ece391_open ((uint8_t*)"."))) { - ece391_fdputs (1, (uint8_t*)"directory open failed\n"); - return 2; - } - - while (0 != (cnt = ece391_read (fd, buf, SBUFSIZE-1))) { - if (-1 == cnt) { - ece391_fdputs (1, (uint8_t*)"directory entry read failed\n"); - return 3; - } - if ('.' == buf[0]) /* a directory... */ - continue; - buf[cnt] = '\0'; - if (0 != do_one_file ((char*)search, (char*)buf)) - return 3; - } - - return 0; -} diff --git a/mp3-LOS/syscalls/ece391hello.c b/mp3-LOS/syscalls/ece391hello.c deleted file mode 100644 index 838d70b..0000000 --- a/mp3-LOS/syscalls/ece391hello.c +++ /dev/null @@ -1,24 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -#define BUFSIZE 1024 - -int main () -{ - int32_t cnt; - uint8_t buf[BUFSIZE]; - - ece391_fdputs (1, (uint8_t*)"Hi, what's your name? "); - if (-1 == (cnt = ece391_read (0, buf, BUFSIZE-1))) { - ece391_fdputs (1, (uint8_t*)"Can't read name from keyboard.\n"); - return 3; - } - buf[cnt] = '\0'; - ece391_fdputs (1, (uint8_t*)"Hello, "); - ece391_fdputs (1, buf); - - return 0; -} - diff --git a/mp3-LOS/syscalls/ece391ls.c b/mp3-LOS/syscalls/ece391ls.c deleted file mode 100644 index 98c81b8..0000000 --- a/mp3-LOS/syscalls/ece391ls.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -#define SBUFSIZE 33 - -int main () -{ - int32_t fd, cnt; - uint8_t buf[SBUFSIZE]; - - if (-1 == (fd = ece391_open ((uint8_t*)"."))) { - ece391_fdputs (1, (uint8_t*)"directory open failed\n"); - return 2; - } - - while (0 != (cnt = ece391_read (fd, buf, SBUFSIZE-1))) { - if (-1 == cnt) { - ece391_fdputs (1, (uint8_t*)"directory entry read failed\n"); - return 3; - } - buf[cnt] = '\n'; - if (-1 == ece391_write (1, buf, cnt + 1)) - return 3; - } - - return 0; -} diff --git a/mp3-LOS/syscalls/ece391pingpong.c b/mp3-LOS/syscalls/ece391pingpong.c deleted file mode 100644 index 6dd7fcd..0000000 --- a/mp3-LOS/syscalls/ece391pingpong.c +++ /dev/null @@ -1,89 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -#define SCREENWIDTH 79 -#define ENDING 2 -#define BUFMAX SCREENWIDTH+ENDING -#define START 1 -#define STARTLOOP START+1 -#define LOOPMAX BUFMAX-ENDING-1 -#define STARTCHAR 'A' -#define ENDCHAR 'Z' - -int main () -{ - int32_t i = 0; - int32_t j = 0; - uint8_t curchar = STARTCHAR; - uint8_t update = 1; - int ret_val; - int garbage; - int rtc_fd; - uint8_t buf[BUFMAX]; - - // Clear buffer - for(i = 0; i < BUFMAX; i++) - buf[i]=' '; - - // Initialize buffer with walls - buf[BUFMAX-1]='\0'; - buf[BUFMAX-2]='\n'; - buf[BUFMAX-3]='|'; - buf[START]='|'; - - // Open and set RTC Frequency - rtc_fd = ece391_open((uint8_t*)"rtc"); - ret_val = 32; - ret_val = ece391_write(rtc_fd, &ret_val, 4); - - while(1) - { - // Move out - for(j = STARTLOOP; j < LOOPMAX; j++) - { - // Clear inner portion of world - for(i = STARTLOOP; i < LOOPMAX; i++) - { - buf[i]=' '; - } - - // Draw character - buf[j] = curchar; - ece391_fdputs (1, buf); - - // Wait for RTC tick - ece391_read(rtc_fd, &garbage, 4); - } - - // Bounce back - for(j = LOOPMAX - 1; j >= STARTLOOP; j--) - { - // Clear inner portion of the world - for(i = STARTLOOP; i < LOOPMAX; i++) - { - buf[i]=' '; - } - - // Draw character - buf[j] = curchar; - ece391_fdputs (1, buf); - - // Wait for RTC tick - ece391_read(rtc_fd, &garbage, 4); - } - - // Edge case on characters - if(curchar == ENDCHAR) - { - curchar = STARTCHAR; - } - else - { - // Update current character - curchar = curchar + update; - } - } - return 0; -} diff --git a/mp3-LOS/syscalls/ece391shell.c b/mp3-LOS/syscalls/ece391shell.c deleted file mode 100644 index 5bcc66f..0000000 --- a/mp3-LOS/syscalls/ece391shell.c +++ /dev/null @@ -1,36 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -#define BUFSIZE 1024 - -int main () -{ - int32_t cnt, rval; - uint8_t buf[BUFSIZE]; - ece391_fdputs (1, (uint8_t*)"Starting 391 Shell\n"); - - while (1) { - ece391_fdputs (1, (uint8_t*)"391OS> "); - if (-1 == (cnt = ece391_read (0, buf, BUFSIZE-1))) { - ece391_fdputs (1, (uint8_t*)"read from keyboard failed\n"); - return 3; - } - if (cnt > 0 && '\n' == buf[cnt - 1]) - cnt--; - buf[cnt] = '\0'; - if (0 == ece391_strcmp (buf, (uint8_t*)"exit")) - return 0; - if ('\0' == buf[0]) - continue; - rval = ece391_execute (buf); - if (-1 == rval) - ece391_fdputs (1, (uint8_t*)"no such command\n"); - else if (256 == rval) - ece391_fdputs (1, (uint8_t*)"program terminated by exception\n"); - else if (0 != rval) - ece391_fdputs (1, (uint8_t*)"program terminated abnormally\n"); - } -} - diff --git a/mp3-LOS/syscalls/ece391sigtest.c b/mp3-LOS/syscalls/ece391sigtest.c deleted file mode 100644 index 415f586..0000000 --- a/mp3-LOS/syscalls/ece391sigtest.c +++ /dev/null @@ -1,81 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -#define BUFSIZE 1024 - -static uint8_t charbuf; -static volatile uint8_t* badbuf = 0; -void segfault_sighandler (int signum); -void alarm_sighandler (int signum); - -int main () -{ - int32_t cnt; - uint8_t buf[BUFSIZE]; - - if (0 != ece391_getargs (buf, BUFSIZE)) { - ece391_fdputs (1, (uint8_t*)"could not read argument\n"); - return 3; - } - - if (buf[0] == '1') { - ece391_fdputs(1, (uint8_t*)"Installing signal handlers\n"); - ece391_set_handler(SEGFAULT, segfault_sighandler); - ece391_set_handler(ALARM, alarm_sighandler); - } - - ece391_fdputs (1, (uint8_t*)"Hi, what's your name? "); - if (-1 == (cnt = ece391_read (0, buf, BUFSIZE-1))) { - ece391_fdputs (1, (uint8_t*)"Can't read name from keyboard.\n"); - return 3; - } - - (*badbuf) = 1; - buf[cnt] = '\0'; - ece391_fdputs (1, (uint8_t*)"Hello, "); - ece391_fdputs (1, buf); - if (charbuf == 1) { - ece391_fdputs(1, (uint8_t*)"success\n"); - } else { - ece391_fdputs(1, (uint8_t*)"failure\n"); - } - - return 0; -} - -void -segfault_sighandler (int signum) -{ - char buf; - uint32_t* eax; - ece391_fdputs(1, (uint8_t*)"Segfault signal handler called, signum: "); - switch (signum) { - case 0: ece391_fdputs(1, (uint8_t*)"0\n"); break; - case 1: ece391_fdputs(1, (uint8_t*)"1\n"); break; - case 2: ece391_fdputs(1, (uint8_t*)"2\n"); break; - case 3: ece391_fdputs(1, (uint8_t*)"3\n"); break; - default: ece391_fdputs(1, (uint8_t*)"invalid\n"); break; - } - ece391_fdputs(1, (uint8_t*)"Press enter to continue...\n"); - ece391_read(0, &buf, 1); - badbuf = &charbuf; - eax = (uint32_t*)(&signum + 7); - *eax = (uint32_t)&charbuf; - - ece391_fdputs(1, (uint8_t*)"Signal handler returning\n"); -} - -void -alarm_sighandler (int signum) -{ - ece391_fdputs(1, (uint8_t*)"Alarm signal handler called, signum: "); - switch (signum) { - case 0: ece391_fdputs(1, (uint8_t*)"0\n"); break; - case 1: ece391_fdputs(1, (uint8_t*)"1\n"); break; - case 2: ece391_fdputs(1, (uint8_t*)"2\n"); break; - case 3: ece391_fdputs(1, (uint8_t*)"3\n"); break; - default: ece391_fdputs(1, (uint8_t*)"invalid\n"); break; - } -} diff --git a/mp3-LOS/syscalls/ece391support.c b/mp3-LOS/syscalls/ece391support.c deleted file mode 100644 index bdc9f45..0000000 --- a/mp3-LOS/syscalls/ece391support.c +++ /dev/null @@ -1,104 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -uint32_t ece391_strlen(const uint8_t* s) -{ - uint32_t len; - - for (len = 0; '\0' != *s; s++, len++); - return len; -} - -void ece391_strcpy(uint8_t* dst, const uint8_t* src) -{ - while ('\0' != (*dst++ = *src++)); -} - -void ece391_fdputs(int32_t fd, const uint8_t* s) -{ - (void)ece391_write (fd, s, ece391_strlen(s)); -} - -int32_t ece391_strcmp(const uint8_t* s1, const uint8_t* s2) -{ - while (*s1 == *s2) { - if (*s1 == '\0') - return 0; - s1++; - s2++; - } - return ((int32_t)*s1) - ((int32_t)*s2); -} - -int32_t ece391_strncmp(const uint8_t* s1, const uint8_t* s2, uint32_t n) -{ - if (0 == n) - return 0; - while (*s1 == *s2) { - if (*s1 == '\0' || --n == 0) - return 0; - s1++; - s2++; - } - return ((int32_t)*s1) - ((int32_t)*s2); -} - -/* Convert a number to its ASCII representation, with base "radix" */ -uint8_t* ece391_itoa(uint32_t value, uint8_t* buf, int32_t radix) -{ - static int8_t lookup[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - uint8_t *newbuf = buf; - int32_t i; - uint32_t newval = value; - - /* Special case for zero */ - if(value == 0) { - buf[0]='0'; - buf[1]='\0'; - return buf; - } - - /* Go through the number one place value at a time, and add the - * correct digit to "newbuf". We actually add characters to the - * ASCII string from lowest place value to highest, which is the - * opposite of how the number should be printed. We'll reverse the - * characters later. */ - while (newval > 0) { - i = newval % radix; - *newbuf = lookup[i]; - newbuf++; - newval /= radix; - } - - /* Add a terminating NULL */ - *newbuf = '\0'; - - /* Reverse the string and return */ - return ece391_strrev(buf); -} - -/* In-place string reversal */ -uint8_t* ece391_strrev(uint8_t* s) -{ - register uint8_t tmp; - register int32_t beg = 0; - register int32_t end = ece391_strlen(s) - 1; - - if (end <= 0) { - return s; - } - - while (beg < end) { - tmp = s[end]; - s[end] = s[beg]; - s[beg] = tmp; - beg++; - end--; - } - - return s; -} - diff --git a/mp3-LOS/syscalls/ece391support.h b/mp3-LOS/syscalls/ece391support.h deleted file mode 100644 index 49db925..0000000 --- a/mp3-LOS/syscalls/ece391support.h +++ /dev/null @@ -1,13 +0,0 @@ -#if !defined(ECE391SUPPORT_H) -#define ECE391SUPPORT_H - -extern uint32_t ece391_strlen(const uint8_t* s); -extern void ece391_strcpy(uint8_t* dst, const uint8_t* src); -extern void ece391_fdputs(int32_t fd, const uint8_t* s); -extern int32_t ece391_strcmp(const uint8_t* s1, const uint8_t* s2); -extern int32_t ece391_strncmp(const uint8_t* s1, const uint8_t* s2, uint32_t n); -extern uint8_t *ece391_itoa(uint32_t value, uint8_t* buf, int32_t radix); -extern uint8_t *ece391_strrev(uint8_t* s); - -#endif /* ECE391SUPPORT_H */ - diff --git a/mp3-LOS/syscalls/ece391syscall.S b/mp3-LOS/syscalls/ece391syscall.S deleted file mode 100644 index a17c6b8..0000000 --- a/mp3-LOS/syscalls/ece391syscall.S +++ /dev/null @@ -1,41 +0,0 @@ -#include "ece391sysnum.h" - -/* - * Rather than create a case for each number of arguments, we simplify - * and use one macro for up to three arguments; the system calls should - * ignore the other registers, and they're caller-saved anyway. - */ -#define DO_CALL(name,number) \ -.GLOBL name ;\ -name: PUSHL %EBX ;\ - MOVL $number,%EAX ;\ - MOVL 8(%ESP),%EBX ;\ - MOVL 12(%ESP),%ECX ;\ - MOVL 16(%ESP),%EDX ;\ - INT $0x80 ;\ - POPL %EBX ;\ - RET - -/* the system call library wrappers */ -DO_CALL(ece391_halt,SYS_HALT) -DO_CALL(ece391_execute,SYS_EXECUTE) -DO_CALL(ece391_read,SYS_READ) -DO_CALL(ece391_write,SYS_WRITE) -DO_CALL(ece391_open,SYS_OPEN) -DO_CALL(ece391_close,SYS_CLOSE) -DO_CALL(ece391_getargs,SYS_GETARGS) -DO_CALL(ece391_vidmap,SYS_VIDMAP) -DO_CALL(ece391_set_handler,SYS_SET_HANDLER) -DO_CALL(ece391_sigreturn,SYS_SIGRETURN) - - -/* Call the main() function, then halt with its return value. */ - -.GLOBAL _start -_start: - CALL main - PUSHL $0 - PUSHL $0 - PUSHL %EAX - CALL ece391_halt - diff --git a/mp3-LOS/syscalls/ece391syscall.h b/mp3-LOS/syscalls/ece391syscall.h deleted file mode 100644 index bf029f3..0000000 --- a/mp3-LOS/syscalls/ece391syscall.h +++ /dev/null @@ -1,35 +0,0 @@ -#if !defined(ECE391SYSCALL_H) -#define ECE391SYSCALL_H - -#include - -/* All calls return >= 0 on success or -1 on failure. */ - -/* - * Note that the system call for halt will have to make sure that only - * the low byte of EBX (the status argument) is returned to the calling - * task. Negative returns from execute indicate that the desired program - * could not be found. - */ -extern int32_t ece391_halt (uint8_t status); -extern int32_t ece391_execute (const uint8_t* command); -extern int32_t ece391_read (int32_t fd, void* buf, int32_t nbytes); -extern int32_t ece391_write (int32_t fd, const void* buf, int32_t nbytes); -extern int32_t ece391_open (const uint8_t* filename); -extern int32_t ece391_close (int32_t fd); -extern int32_t ece391_getargs (uint8_t* buf, int32_t nbytes); -extern int32_t ece391_vidmap (uint8_t** screen_start); -extern int32_t ece391_set_handler (int32_t signum, void* handler); -extern int32_t ece391_sigreturn (void); - -enum signums { - DIV_ZERO = 0, - SEGFAULT, - INTERRUPT, - ALARM, - USER1, - NUM_SIGNALS -}; - -#endif /* ECE391SYSCALL_H */ - diff --git a/mp3-LOS/syscalls/ece391syserr.c b/mp3-LOS/syscalls/ece391syserr.c deleted file mode 100644 index 716ecc9..0000000 --- a/mp3-LOS/syscalls/ece391syserr.c +++ /dev/null @@ -1,346 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -#define NEG_FD -1073741823 -#define BIG_FD 1073741823 -#define BIG_NUM 1073741823 -#define NEG_NUM -1073741823 - -/* call_sys - * This function calls the system call #(num) - * num is the syscall number to be called - * returns 0 on success, -1 on failure - */ -int call_sys(int num) -{ - int fail; - asm volatile - ( - "movl %1, %%eax\n\t" - "int $0x80" - : "=a"(fail) - : "g"(num) - ); - return fail; -} - -/* TEST 1 err_neg_fd - * tries to call syscalls with file descriptor < 0 - * prints "[TEST_NAME]: PASS" if behavior is EXPECTED - * and then returns 0 - * prints "[TEST_NAME]: FAIL" if behavior is UNEXPECTED - * and then returns 2 - */ -int err_neg_fd(void) { - uint8_t buf[32]; - int fail = 0; - if (-1 != ece391_read(NEG_FD, buf, 31)) { - fail = 2; - ece391_fdputs (1, (uint8_t*)"read fail\n"); - } - if (-1 != ece391_write(NEG_FD, buf, 31)) { - fail = 2; - ece391_fdputs (1, (uint8_t*)"write fail\n"); - } - if (-1 != ece391_close(NEG_FD)) { - fail = 2; - ece391_fdputs (1, (uint8_t*)"close fail\n"); - } - if(fail) { - ece391_fdputs (1, (uint8_t*)"err_neg_fd: FAIL\n"); - } else { - ece391_fdputs (1, (uint8_t*)"err_neg_fd: PASS\n"); - } - - return fail; -} - - -/* TEST 2 err_big_fd - * tries to write to a file with file descriptor > 7 - * prints "[TEST_NAME]: PASS" if behavior is EXPECTED - * and then returns 0 - * prints "[TEST_NAME]: FAIL" if behavior is UNEXPECTED - * and then returns 2 - */ -int err_big_fd(void) { - uint8_t buf[32]; - int fail = 0; - if (-1 != ece391_read(BIG_FD, buf, 31)) { - fail = 2; - ece391_fdputs (1, (uint8_t*)"read fail\n"); - } - if (-1 != ece391_write(BIG_FD, buf, 31)) { - fail = 2; - ece391_fdputs (1, (uint8_t*)"write fail\n"); - } - if (-1 != ece391_close(BIG_FD)) { - fail = 2; - ece391_fdputs (1, (uint8_t*)"close fail\n"); - } - if(fail) { - ece391_fdputs (1, (uint8_t*)"err_big_fd: FAIL\n"); - } else { - ece391_fdputs (1, (uint8_t*)"err_big_fd: PASS\n"); - } - - return fail; -} - - -/* TEST 3 err_open_lots - * calls open correctly seven times - * prints "[TEST_NAME]: PASS" if behavior is EXPECTED - * and then returns 0 - * prints "[TEST_NAME]: FAIL" if behavior is UNEXPECTED - * and then returns 2 - */ -int err_open_lots(void) { - int32_t i, cnt = 0; - - // fd = 0,1 taken, so we should be able to open 6 files (2,3,4,5,6,7) - // the last file open should fail - for (i = 0; i < 7; i++) { - if (-1 == ece391_open ((uint8_t*)".")) { - cnt++; - } - } - //close all fds that were just opened. - for(i = 2; i < 8; i++) - { - ece391_close(i); - } - - if (cnt == 1) { - ece391_fdputs(1, (uint8_t*)"err_open_lots: PASS\n"); - return 0; - } else { - ece391_fdputs (1, (uint8_t*)"err_open_lots: FAIL\n"); - return 2; - } -} - - -/* TEST 4 err_open - * tries to open slightly incorrect filenames - * prints "[TEST_NAME]: PASS" if behavior is EXPECTED - * and then returns 0 - * prints "[TEST_NAME]: FAIL" if behavior is UNEXPECTED - * and then returns 2 - */ -int err_open(void) { - int fail = 0; // 0 if success, != 0 if fail - // test with string that matches filename with additional character - if (-1 != ece391_open ((uint8_t*)"helloo")) { - ece391_fdputs (1, (uint8_t*)"'helloo' fail\n"); - fail = 2; - } - - // test with string that is short of filename by one character - if (-1 != ece391_open ((uint8_t*)"shel")) { - ece391_fdputs (1, (uint8_t*)"'shel' fail\n"); - fail = 2; - } - - // test with empty string - if (-1 != ece391_open ((uint8_t*)"")) { - ece391_fdputs (1, (uint8_t*)"empty string fail\n"); - fail = 2; - } - - if (fail) { - ece391_fdputs (1, (uint8_t*)"err_open: FAIL\n"); - } else { - ece391_fdputs (1, (uint8_t*)"err_open: PASS\n"); - } - return fail; -} - - -/* TEST 5 err_unopened - * tries to close all fd. - * tries to read and write from unopened fd's 2-7 - * prints "[TEST_NAME]: PASS" if behavior is EXPECTED - * and then returns 0 - * prints "[TEST_NAME]: FAIL" if behavior is UNEXPECTED - * and then returns 2 - */ -int err_unopened(void) { - int fail = 0, i; - uint8_t buf[32]; - // try to close all fd's. 0 and 1 are stdin and stdout. The rest - // haven't been opened. Nothing should be able to be closed - for (i = 0; i < 8; i++) { - if (-1 != ece391_close(i)) { - ece391_fdputs (1, (uint8_t*)"close unopened or invalid fd fail\n"); - fail = 2; - } - } - for (i = 2; i < 8; i++) { - if (-1 != ece391_read(i, buf, 31)) { - ece391_fdputs (1, (uint8_t*)"read from unopened fd fail\n"); - fail = 2; - } - } - for (i = 2; i < 8; i++) { - if (-1 != ece391_write(i, buf, 31)) { - ece391_fdputs (1, (uint8_t*)"write to unopened fd fail\n"); - fail = 2; - } - } - if(fail) { - ece391_fdputs (1, (uint8_t*)"err_unopened: FAIL\n"); - } else { - ece391_fdputs (1, (uint8_t*)"err_unopened: PASS\n"); - } - return fail; -} - -/* TEST 6 err_vidmap - * tries to call vidmap with a NULL ptr and an address in the kernel - * prints "[TEST_NAME]: PASS" if behavior is EXPECTED - * and then returns 0 - * prints "[TEST_NAME]: FAIL" if behavior is UNEXPECTED - * and then returns 2 - */ -int err_vidmap(void) { - int fail = 0; // 0 if success, != 0 if fail - // test with NULL pointer - if (-1 != ece391_vidmap((uint8_t **) 0x0)) { - ece391_fdputs (1, (uint8_t*)"Null pointer fail\n"); - fail = 2; - } - - if (-1 != ece391_vidmap((uint8_t **) 0x400000)) { - ece391_fdputs (1, (uint8_t*)"Kernel pointer fail fail\n"); - fail = 2; - } - - if (fail) { - ece391_fdputs (1, (uint8_t*)"err_vidmap: FAIL\n"); - } else { - ece391_fdputs (1, (uint8_t*)"err_vidmap: PASS\n"); - } - - return fail; -} - -/* TEST 7 err_stdin_out - * write to stdin read from stdout - * prints "[TEST_NAME]: PASS" if behavior is EXPECTED - * and then returns 0 - * prints "[TEST_NAME]: FAIL" if behavior is UNEXPECTED - * and then returns 2 - */ - - int err_stdin_out(void) { - int fail = 0; - uint8_t buf[32]; - - if (-1 != ece391_write(0, buf, 31)) { - ece391_fdputs (1, (uint8_t*)"write to stdin fail\n"); - fail = 2; - } - - if (-1 != ece391_read(1, buf, 31)) { - ece391_fdputs (1, (uint8_t*)"read from stdout fail\n"); - fail = 2; - } - - if (fail) { - ece391_fdputs (1, (uint8_t*)"err_stdin_out: FAIL\n"); - } else { - ece391_fdputs (1, (uint8_t*)"err_stdin_out: PASS\n"); - } - - return fail; - } - - /* TEST 8 err_syscall_num - * call syscall 0, NEG_NUM, and BIG_NUM - * prints "[TEST_NAME]: PASS" if behavior is EXPECTED - * and then returns 0 - * prints "[TEST_NAME]: FAIL" if behavior is UNEXPECTED - * and then returns 2 - */ - - int err_syscall_num(void) - { - int fail = 0; - - if (-1 != call_sys(BIG_NUM)) { - ece391_fdputs (1, (uint8_t*)"syscall 0 fail\n"); - fail = 2; - } - if (-1 != call_sys(NEG_NUM)) { - ece391_fdputs (1, (uint8_t*)"big num syscall fail\n"); - fail = 2; - } - if (-1 != call_sys(0)) { - ece391_fdputs (1, (uint8_t*)"neg num syscall fail\n"); - fail = 2; - } - - if (fail) { - ece391_fdputs (1, (uint8_t*)"err_syscall_num: FAIL\n"); - } else { - ece391_fdputs (1, (uint8_t*)"err_syscall_num: PASS\n"); - } - - return fail; - } - - -int main () -{ - int32_t cnt, select; - uint8_t buf[128]; - int fail = 0; - - ece391_fdputs (1, (uint8_t*)"Choose from tests 1-8. 0 to run all: "); - if (-1 == (cnt = ece391_read (0, buf, 127))) { - ece391_fdputs (1, (uint8_t*)"Can't read test #\n"); - return 2; - } - select = (int)(buf[0] - '0'); - - switch(select) { - case 0: - fail += err_neg_fd(); - fail += err_big_fd(); - fail += err_open_lots(); - fail += err_open(); - fail += err_unopened(); - fail += err_vidmap(); - fail += err_stdin_out(); - fail += err_syscall_num(); - if(fail) { - ece391_fdputs (1, (uint8_t*)"\nOverall Tests: FAIL\n"); - } else { - ece391_fdputs (1, (uint8_t*)"\nOverall Tests: PASS\n"); - } - return fail; - case 1: - return err_neg_fd(); - case 2: - return err_big_fd(); - case 3: - return err_open_lots(); - case 4: - return err_open(); - case 5: - return err_unopened(); - case 6: - return err_vidmap(); - case 7: - return err_stdin_out(); - case 8: - return err_syscall_num(); - default: - ece391_fdputs (1, (uint8_t*)"Invalid test number. Choose from tests 1-8 or 0"); - break; - } - return 0; -} diff --git a/mp3-LOS/syscalls/ece391sysnum.h b/mp3-LOS/syscalls/ece391sysnum.h deleted file mode 100644 index 052f3b2..0000000 --- a/mp3-LOS/syscalls/ece391sysnum.h +++ /dev/null @@ -1,15 +0,0 @@ -#if !defined(ECE391SYSNUM_H) -#define ECE391SYSNUM_H - -#define SYS_HALT 1 -#define SYS_EXECUTE 2 -#define SYS_READ 3 -#define SYS_WRITE 4 -#define SYS_OPEN 5 -#define SYS_CLOSE 6 -#define SYS_GETARGS 7 -#define SYS_VIDMAP 8 -#define SYS_SET_HANDLER 9 -#define SYS_SIGRETURN 10 - -#endif /* ECE391SYSNUM_H */ diff --git a/mp3-LOS/syscalls/ece391testprint.c b/mp3-LOS/syscalls/ece391testprint.c deleted file mode 100644 index 2f7bb12..0000000 --- a/mp3-LOS/syscalls/ece391testprint.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -#include "ece391support.h" -#include "ece391syscall.h" - -int main () -{ - - ece391_fdputs (1, (uint8_t*)"Hello, if this ran, the program was correct. Yay!\n"); - - return 0; -} - diff --git a/mp3-LOS/syscalls/to_fsdir/cat b/mp3-LOS/syscalls/to_fsdir/cat deleted file mode 100644 index aa7ac9b..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/cat and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/counter b/mp3-LOS/syscalls/to_fsdir/counter deleted file mode 100644 index 549768c..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/counter and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/grep b/mp3-LOS/syscalls/to_fsdir/grep deleted file mode 100644 index b785b70..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/grep and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/hello b/mp3-LOS/syscalls/to_fsdir/hello deleted file mode 100644 index 80fff89..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/hello and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/ls b/mp3-LOS/syscalls/to_fsdir/ls deleted file mode 100644 index 3dda063..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/ls and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/pingpong b/mp3-LOS/syscalls/to_fsdir/pingpong deleted file mode 100644 index 7b17147..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/pingpong and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/shell b/mp3-LOS/syscalls/to_fsdir/shell deleted file mode 100644 index 84c531e..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/shell and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/sigtest b/mp3-LOS/syscalls/to_fsdir/sigtest deleted file mode 100644 index 896c34f..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/sigtest and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/syserr b/mp3-LOS/syscalls/to_fsdir/syserr deleted file mode 100644 index 7d6c4c2..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/syserr and /dev/null differ diff --git a/mp3-LOS/syscalls/to_fsdir/testprint b/mp3-LOS/syscalls/to_fsdir/testprint deleted file mode 100644 index 30c1ea0..0000000 Binary files a/mp3-LOS/syscalls/to_fsdir/testprint and /dev/null differ