/* * S-IDE - the Small Integrated Development Environment * Copyright (c) 2002, 2005 Clement Vasseur * Adaptation for use with PedroM - Copyright (C) 2003, 2005 Patrick Pelissier * Nostub port and further development - Copyright (C) 2005-2007 Kevin Kofler * * This program is free software ; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software Foundation; * either version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Version 0.1.P8 (PpHd): * * List of changes: * + Kernel Mode * + No more Gray * + No more Syntax Highling * + Bigger Font much faster * + Much more key sensitive ! * + Only for TI-92+ * + New way for compiling * + Secondary text * + <> + LEFT/RIGHT : Left word, right word * + Replace * + Execute * * Version 0.1.P8 nostub (Kevin Kofler): * * List of changes: * 2005-03-05 Kevin Kofler r1 * + Back to _nostub mode ;-) * + Add error message for unsupported on-calc compatibility * 2005-03-06 Kevin Kofler r2 * + Readd on-calc compatibility, remove error message * + Use TIGCC IDE * + Readd grayscale and syntax highlighting * + Delete register qualifiers (ignored by GCC) * + Fix compiler warnings * + Use low-power mode * + Fix clipboard key combos * + Use AMS clipboard * + Fix clipboard locking bug * 2005-03-07 Kevin Kofler r3 * + Improve syntax highlighting * + Proper (protection-aware) way to execute compilers (based on pstarter) * + Change default command for "Exec" to !_p() * + Fix spelling of "cannot" * + Fix screen redrawing leaving junk pixels on the screen * + Fix cut TI-89 status line * + Fix secondary text locking bug * + Fix secondary text display * 2007-03-18 Kevin Kofler r4 * + Completely drop support for PedroM and AMS 1 (MIN_AMS was already 204 anyway) * + Clean up indentation, get rid of tabs * + Fix strict-aliasing violation * + Redirect trap #0 to fix idle() for grayscale * + Use AMS event loop instead of polling * + Use MLink format relocs * 2007-03-19 Kevin Kofler r5 * + Unhook trap #0 while running another program * 2007-03-19 Kevin Kofler r6 * + Hook trap #4 for APD, reset keyboard repeat there instead of turn_off() * + Use internal F-Line emulator and lower MIN_AMS to 200 * + Remove turn_off(), replace all uses with off() * + Remove handling of CM_APD and CM_OFF which are apparently never used * + Handle KEY_OFF and KEY_OFF2 * 2007-04-30 Kevin Kofler r7 * + Update FSF address * + Use MLink-format ROM_CALLs instead of internal F-Line emulator * 2007-04-30 Kevin Kofler r8 * + Add support for DIAMOND+key=char combos on the TI-89 * 2007-05-15 Kevin Kofler r9 * + Rebuild with latest ld-tigcc from CVS to fix select_right crash */ //GENERAL INCLUDE #include #include #include #include #include //LOW LEVEL INCLUDE #include #include #include #include #include #include #include #include #include //INPUT INCLUDE #include #include #include //OUTPUT INCLUDE #include #include //DEFINE #define MOD_2ND 0x1 #define MOD_DIAMOND 0x2 #define MOD_SHIFT 0x4 #define MOD_ALPHA 0x8 #define XMOD_ALOCK 0x0001 #define XMOD_CAPS 0x8000 //EXCERPT FROM #define OSModKeyStatus (*((unsigned short*)(_rom_call_addr(431)))) #define ST_flags (*((unsigned long*)(_rom_call_addr(443)))) #define TokenizeName _rom_call(unsigned short,(const char*,unsigned char*),3E9) //END OF THE EXCERPT extern _DEREF_INT_HANDLER trap_0_hook_impl; #define trap_0_hook (&trap_0_hook_impl) extern INT_HANDLER old_trap_0; static char TextFont46[] = { /* 0 to 31 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x08,0x0d,0x07, 0x0d,0x05,0x0c,0x08,0x0d,0x06,0x05,0x08,0x0c,0x08, 0x0d,0x0a,0x0d,0x00,0x0c,0x08,0x0f,0x0a,0x0e,0x02, 0x0c,0x08,0x0f,0x0d,0x0f,0x01,0x04,0x0e,0x0a,0x05, 0x06,0x05,0x00,0x04,0x0e,0x0f,0x04,0x00,0x00,0x07, 0x0f,0x07,0x00,0x00,0x05,0x03,0x0f,0x03,0x05,0x00, 0x00,0x0e,0x02,0x07,0x02,0x00,0x00,0x02,0x05,0x0f, 0x0a,0x0e,0x0f,0x06,0x0f,0x06,0x06,0x00,0x00,0x01, 0x05,0x0f,0x04,0x00,0x06,0x09,0x0f,0x0b,0x0f,0x00, 0x00,0x01,0x01,0x0a,0x04,0x00,0x00,0x0f,0x0f,0x0f, 0x0f,0x00,0x00,0x07,0x0f,0x0f,0x07,0x00,0x00,0x0e, 0x0f,0x0f,0x0e,0x00,0x00,0x06,0x0f,0x0f,0x00,0x00, 0x00,0x0f,0x0f,0x06,0x00,0x00,0x02,0x04,0x0f,0x04, 0x02,0x00,0x04,0x02,0x0f,0x02,0x04,0x00,0x04,0x0e, 0x05,0x04,0x04,0x00,0x02,0x02,0x0a,0x07,0x02,0x00, 0x07,0x0f,0x0f,0x0f,0x07,0x00,0x0e,0x0f,0x0f,0x0f, 0x0e,0x00,0x06,0x0f,0x06,0x06,0x00,0x00,0x09,0x09, 0x09,0x06,0x00,0x00,0x06,0x09,0x09,0x09,0x00,0x00, 0x07,0x08,0x08,0x07,0x00,0x00,0x07,0x08,0x0f,0x08, 0x07,0x00, /* 32 to 127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00, 0x02,0x00,0x05,0x05,0x00,0x00,0x00,0x00,0x02,0x07, 0x02,0x07,0x02,0x00,0x03,0x06,0x07,0x03,0x06,0x00, 0x05,0x01,0x02,0x04,0x05,0x00,0x02,0x05,0x02,0x05, 0x03,0x00,0x02,0x02,0x02,0x00,0x00,0x00,0x01,0x02, 0x02,0x02,0x01,0x00,0x02,0x01,0x01,0x01,0x02,0x00, 0x00,0x05,0x02,0x05,0x00,0x00,0x00,0x02,0x07,0x02, 0x00,0x00,0x00,0x00,0x02,0x02,0x04,0x00,0x00,0x00, 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, 0x01,0x01,0x02,0x04,0x04,0x00,0x03,0x05,0x05,0x05, 0x06,0x00,0x02,0x06,0x02,0x02,0x07,0x00,0x07,0x01, 0x03,0x04,0x07,0x00,0x07,0x01,0x02,0x01,0x06,0x00, 0x05,0x05,0x07,0x01,0x01,0x00,0x07,0x04,0x07,0x01, 0x06,0x00,0x03,0x04,0x06,0x05,0x03,0x00,0x07,0x01, 0x02,0x04,0x04,0x00,0x03,0x05,0x02,0x05,0x06,0x00, 0x06,0x05,0x03,0x01,0x06,0x00,0x00,0x02,0x00,0x02, 0x00,0x00,0x00,0x02,0x00,0x02,0x04,0x00,0x01,0x02, 0x04,0x02,0x01,0x00,0x00,0x07,0x00,0x07,0x00,0x00, 0x04,0x02,0x01,0x02,0x04,0x00,0x06,0x01,0x02,0x00, 0x02,0x00,0x06,0x01,0x05,0x05,0x02,0x00,0x02,0x05, 0x07,0x05,0x05,0x00,0x06,0x05,0x06,0x05,0x06,0x00, 0x03,0x04,0x04,0x04,0x03,0x00,0x06,0x05,0x05,0x05, 0x06,0x00,0x07,0x04,0x06,0x04,0x07,0x00,0x07,0x04, 0x06,0x04,0x04,0x00,0x03,0x04,0x05,0x05,0x03,0x00, 0x05,0x05,0x07,0x05,0x05,0x00,0x07,0x02,0x02,0x02, 0x07,0x00,0x01,0x01,0x01,0x05,0x03,0x00,0x05,0x05, 0x06,0x05,0x05,0x00,0x04,0x04,0x04,0x04,0x07,0x00, 0x05,0x07,0x07,0x05,0x05,0x00,0x06,0x05,0x05,0x05, 0x05,0x00,0x02,0x05,0x05,0x05,0x02,0x00,0x06,0x05, 0x06,0x04,0x04,0x00,0x02,0x05,0x05,0x06,0x03,0x00, 0x06,0x05,0x06,0x05,0x05,0x00,0x03,0x04,0x02,0x01, 0x06,0x00,0x07,0x02,0x02,0x02,0x02,0x00,0x05,0x05, 0x05,0x05,0x07,0x00,0x05,0x05,0x05,0x02,0x02,0x00, 0x05,0x05,0x07,0x07,0x05,0x00,0x05,0x05,0x02,0x05, 0x05,0x00,0x05,0x05,0x02,0x02,0x02,0x00,0x07,0x01, 0x02,0x04,0x07,0x00,0x03,0x02,0x02,0x02,0x03,0x00, 0x04,0x04,0x02,0x01,0x01,0x00,0x06,0x02,0x02,0x02, 0x06,0x00,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x07,0x00,0x02,0x01,0x00,0x00,0x00,0x00, 0x00,0x03,0x05,0x05,0x03,0x00,0x04,0x06,0x05,0x05, 0x06,0x00,0x00,0x03,0x04,0x04,0x03,0x00,0x01,0x03, 0x05,0x05,0x03,0x00,0x00,0x03,0x05,0x06,0x03,0x00, 0x03,0x04,0x06,0x04,0x04,0x00,0x00,0x03,0x05,0x03, 0x01,0x06,0x04,0x06,0x05,0x05,0x05,0x00,0x02,0x00, 0x06,0x02,0x07,0x00,0x00,0x01,0x00,0x01,0x05,0x02, 0x04,0x05,0x06,0x05,0x05,0x00,0x02,0x02,0x02,0x02, 0x01,0x00,0x00,0x05,0x07,0x05,0x05,0x00,0x00,0x06, 0x05,0x05,0x05,0x00,0x00,0x02,0x05,0x05,0x02,0x00, 0x00,0x06,0x05,0x05,0x06,0x04,0x00,0x03,0x05,0x05, 0x03,0x01,0x00,0x03,0x04,0x04,0x04,0x00,0x00,0x03, 0x06,0x01,0x06,0x00,0x02,0x07,0x02,0x02,0x01,0x00, 0x00,0x05,0x05,0x05,0x03,0x00,0x00,0x05,0x05,0x05, 0x02,0x00,0x00,0x05,0x05,0x07,0x05,0x00,0x00,0x05, 0x02,0x02,0x05,0x00,0x00,0x05,0x05,0x03,0x01,0x06, 0x00,0x07,0x01,0x02,0x07,0x00,0x03,0x02,0x04,0x02, 0x03,0x00,0x02,0x02,0x02,0x02,0x02,0x00,0x06,0x02, 0x01,0x02,0x06,0x00,0x00,0x02,0x05,0x00,0x00,0x00, 0x07,0x07,0x07,0x07,0x07,0x00, /* 128 to 255 */ 0x05,0x0a,0x0a,0x05,0x00,0x00,0x02,0x05,0x06,0x05, 0x0a,0x00,0x0f,0x09,0x08,0x08,0x08,0x00,0x05,0x0a, 0x06,0x06,0x00,0x00,0x00,0x02,0x05,0x0f,0x00,0x00, 0x06,0x08,0x06,0x09,0x06,0x00,0x06,0x08,0x06,0x08, 0x06,0x00,0x0b,0x07,0x08,0x06,0x06,0x00,0x06,0x09, 0x0f,0x09,0x06,0x00,0x08,0x04,0x06,0x09,0x00,0x00, 0x0f,0x04,0x03,0x04,0x03,0x02,0x0f,0x05,0x05,0x05, 0x05,0x00,0x00,0x0f,0x05,0x05,0x09,0x00,0x02,0x05, 0x06,0x04,0x04,0x00,0x0f,0x04,0x02,0x04,0x0f,0x00, 0x00,0x07,0x0a,0x04,0x00,0x00,0x07,0x0a,0x02,0x04, 0x03,0x00,0x04,0x0e,0x0e,0x04,0x00,0x00,0x0b,0x0b, 0x0b,0x07,0x02,0x00,0x06,0x09,0x09,0x06,0x09,0x00, 0x00,0x05,0x09,0x0b,0x05,0x00,0x00,0x00,0x07,0x06, 0x07,0x00,0x06,0x09,0x0f,0x04,0x03,0x00,0x06,0x00, 0x06,0x06,0x03,0x00,0x0e,0x08,0x08,0x00,0x00,0x00, 0x0e,0x04,0x04,0x00,0x00,0x00,0x0f,0x09,0x06,0x06, 0x09,0x00,0x0f,0x09,0x06,0x01,0x06,0x00,0x02,0x04, 0x08,0x04,0x0f,0x00,0x01,0x0f,0x02,0x0f,0x08,0x00, 0x04,0x02,0x01,0x02,0x0f,0x00,0x01,0x02,0x04,0x0f, 0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x00,0x04,0x00, 0x04,0x04,0x04,0x00,0x01,0x07,0x0a,0x07,0x08,0x00, 0x02,0x05,0x0e,0x0a,0x0e,0x00,0x00,0x09,0x06,0x06, 0x09,0x00,0x09,0x05,0x0f,0x0f,0x02,0x00,0x04,0x04, 0x00,0x04,0x04,0x00,0x07,0x08,0x07,0x01,0x0e,0x00, 0x03,0x0a,0x04,0x04,0x00,0x00,0x06,0x09,0x0b,0x09, 0x06,0x00,0x06,0x09,0x07,0x00,0x0f,0x00,0x03,0x06, 0x0c,0x06,0x03,0x00,0x00,0x0f,0x01,0x00,0x00,0x00, 0x00,0x00,0x0e,0x00,0x00,0x00,0x06,0x09,0x09,0x0b, 0x06,0x00,0x00,0x0e,0x00,0x00,0x00,0x00,0x06,0x09, 0x06,0x00,0x00,0x00,0x06,0x0f,0x06,0x00,0x00,0x00, 0x02,0x05,0x01,0x02,0x07,0x00,0x02,0x01,0x03,0x01, 0x03,0x00,0x01,0x0d,0x01,0x01,0x00,0x00,0x0a,0x0a, 0x0a,0x0e,0x08,0x00,0x07,0x0b,0x07,0x03,0x03,0x00, 0x00,0x00,0x00,0x04,0x00,0x00,0x09,0x06,0x06,0x09, 0x00,0x00,0x02,0x06,0x02,0x07,0x00,0x00,0x06,0x09, 0x06,0x00,0x0f,0x00,0x0c,0x06,0x03,0x06,0x0c,0x00, 0x01,0x05,0x0a,0x05,0x00,0x00,0x03,0x02,0x02,0x0a, 0x04,0x00,0x00,0x05,0x0b,0x05,0x00,0x00,0x04,0x00, 0x04,0x09,0x06,0x00,0x0c,0x0e,0x0a,0x0e,0x0a,0x00, 0x06,0x0e,0x0a,0x0e,0x0a,0x00,0x04,0x0e,0x0a,0x0e, 0x0a,0x00,0x0e,0x0e,0x0a,0x0e,0x0a,0x00,0x0a,0x0e, 0x0a,0x0e,0x0a,0x00,0x02,0x0e,0x0a,0x0e,0x0a,0x00, 0x05,0x0a,0x0f,0x0a,0x03,0x00,0x06,0x08,0x06,0x02, 0x06,0x00,0x06,0x0e,0x08,0x0e,0x08,0x0e,0x0c,0x0e, 0x08,0x0e,0x08,0x0e,0x04,0x0e,0x08,0x0e,0x08,0x0e, 0x0a,0x0e,0x08,0x0e,0x08,0x0e,0x06,0x0e,0x04,0x04, 0x0e,0x00,0x0c,0x0e,0x04,0x04,0x0e,0x00,0x04,0x0e, 0x04,0x04,0x0e,0x00,0x0a,0x0e,0x04,0x04,0x0e,0x00, 0x0e,0x05,0x0d,0x05,0x0e,0x00,0x0e,0x00,0x0d,0x0b, 0x09,0x00,0x04,0x02,0x04,0x0a,0x04,0x00,0x04,0x08, 0x04,0x0a,0x04,0x00,0x04,0x0a,0x04,0x0a,0x04,0x00, 0x05,0x0a,0x04,0x0a,0x04,0x00,0x0a,0x00,0x04,0x0a, 0x04,0x00,0x00,0x00,0x0a,0x04,0x0a,0x00,0x06,0x09, 0x0b,0x0d,0x06,0x00,0x08,0x04,0x0a,0x0a,0x04,0x00, 0x02,0x04,0x0a,0x0a,0x04,0x00,0x0e,0x00,0x0a,0x0a, 0x04,0x00,0x0a,0x00,0x0a,0x0a,0x04,0x00,0x02,0x04, 0x09,0x05,0x02,0x00,0x08,0x0e,0x09,0x0f,0x08,0x00, 0x02,0x05,0x06,0x05,0x0a,0x00,0x0c,0x0e,0x0a,0x0e, 0x0a,0x00,0x06,0x0e,0x0a,0x0e,0x0a,0x00,0x04,0x0e, 0x0a,0x0e,0x0a,0x00,0x0e,0x0e,0x0a,0x0e,0x0a,0x00, 0x0a,0x0e,0x0a,0x0e,0x0a,0x00,0x02,0x0e,0x0a,0x0e, 0x0a,0x00,0x05,0x0a,0x0f,0x0a,0x03,0x00,0x06,0x08, 0x06,0x02,0x06,0x00,0x06,0x0e,0x08,0x0e,0x08,0x0e, 0x0c,0x0e,0x08,0x0e,0x08,0x0e,0x04,0x0e,0x08,0x0e, 0x08,0x0e,0x0a,0x0e,0x08,0x0e,0x08,0x0e,0x06,0x0e, 0x04,0x04,0x0e,0x00,0x0c,0x0e,0x04,0x04,0x0e,0x00, 0x04,0x0e,0x04,0x04,0x0e,0x00,0x0a,0x0e,0x04,0x04, 0x0e,0x00,0x0e,0x05,0x0d,0x05,0x0e,0x00,0x0e,0x00, 0x0d,0x0b,0x09,0x00,0x04,0x02,0x04,0x0a,0x04,0x00, 0x04,0x08,0x04,0x0a,0x04,0x00,0x04,0x0a,0x04,0x0a, 0x04,0x00,0x05,0x0a,0x04,0x0a,0x04,0x00,0x0a,0x00, 0x04,0x0a,0x04,0x00,0x04,0x00,0x0f,0x00,0x04,0x00, 0x06,0x0b,0x0d,0x06,0x00,0x00,0x08,0x04,0x0a,0x0a, 0x04,0x00,0x02,0x04,0x0a,0x0a,0x04,0x00,0x0e,0x00, 0x0a,0x0a,0x04,0x00,0x0a,0x00,0x0a,0x0a,0x04,0x00, 0x02,0x09,0x0d,0x02,0x0e,0x00,0x08,0x0e,0x09,0x0f, 0x08,0x00,0x05,0x05,0x02,0x01,0x06,0x00 }; /* 0: operator, 1: letter, -1: digit */ static char chartypes[256]={ /*0*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /*1*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /*2*/ 0,0,0,-1,-1,0,-1,0,0,0,0,0,0,0,-1,0, // X X X # $ X & etc.... /*3*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //number are ten first case /*4*/ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*5*/ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, /*6*/ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*7*/ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, /*8*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*9*/ 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, /*A*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0, /*B*/ 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, /*C*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*D*/ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /*E*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /*F*/ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1 }; #define BUF_SIZE 512 #define LF '\n' #define CR '\r' #define LineMax 601 #define FileDelimiter ' ' #define CFileDelimiter " " #define FILE_SYSTEM "sidetext\\fsys" typedef short error_t; enum { INPUT_NUM, INPUT_PATH, INPUT_ALL }; enum { ERR_NONE, ERR_MEMORY, ERR_EXEC, ERR_FILE }; enum { EXEC_OTH, EXEC_SC, EXEC_AS }; enum { C_WHITE, C_LIGHTGRAY, C_DARKGRAY, C_BLACK, C_INVERSE = 128 }; enum { I_NONE, I_SECOND, I_DIAMOND, I_SHIFT, I_ALPHA, I_ALOCK, I_CAPS }; enum { K_SECOND = 4096, K_DIAMOND = 8192, K_SHIFT = 16384 }; enum { K_UP = 338, K_DOWN = 344, K_RIGHT = 340, K_LEFT = 337, K_COPY_92 = K_DIAMOND + 'C', K_CUT_92 = K_DIAMOND + 'X', K_PASTE_92 = K_DIAMOND + 'V', K_F1 = 268, K_F2 = 269, K_F3 = 270, K_F4 = 271, K_F5 = 272, K_F6 = 273, K_F7 = 274, K_F8 = 275, K_ESC = 264, K_QUIT = 4360, K_APPS = 265, K_SWITCH = 4361, K_MODE = 266, K_BACKSPACE = 257, K_INS = 4353, K_CLEAR = 263, K_VARLNK = 4141, K_CHAR = 4139, K_ENTER = 13, K_STO = 258, K_ON = 267, K_OFF = 4363, K_COPY_89 = K_DIAMOND + K_SHIFT, K_CUT_89 = K_DIAMOND + K_SECOND, K_PASTE_89 = K_DIAMOND + K_ESC }; #define Q(ti89value,ti92pv200value) (TI89?(ti89value):(ti92pv200value)) #define K_COPY Q(K_COPY_89,K_COPY_92) #define K_CUT Q(K_CUT_89,K_CUT_92) #define K_PASTE Q(K_PASTE_89,K_PASTE_92) void *buffer; long buffer_diff; char *filename; char *file_ptr; char *end_ptr; char *page_ptr; char *curs_ptr; char *gap_ptr; char exec_name[28]; char exec_name2[28]; int line, select; int penCol, penRow, penColor; int curCol, curRow; short key_delay, key_rate; short disp_indic; char text2_name[28]; unsigned short text2_pos; BOOL modified, refresh; BOOL auto_code; BOOL color_syntax; BOOL auto_indent; char find_str[32]; char replace_str[32]; INT_HANDLER old_trap_4; //My Own Variable unsigned short isDiese = 0; //Syntax highlighting DEFINE_INT_HANDLER(trap_4_hook) { ExecuteHandler(old_trap_4); OSInitKeyInitDelay(key_delay); OSInitBetweenKeyDelay(key_rate); } void init_side(void) { strcpy(exec_name, "as(\"!\",\"!_p\")"); strcpy(exec_name2, "util\\uview(\"!\")"); strcpy(text2_name, "as_error"); strcpy(replace_str, ""); strcpy(find_str, ""); key_delay = 336; key_rate = 48; disp_indic = I_NONE; auto_code = TRUE; color_syntax = TRUE; auto_indent = TRUE; text2_pos = 0; } static void draw_hline(short x1, short x2, short y, short color) { unsigned char *addr = buffer + (y<<5) - (y<<1) + (x1>>3); unsigned char mask = 0x80 >> (x1 & 7); while (x1++ <= x2) { if (color & 2) *addr |= mask; else *addr &= ~mask; if (color & 1) *(addr + buffer_diff) |= mask; else *(addr + buffer_diff) &= ~mask; asm ("ror.b #1,%0;bcc.s 0f;addq.l #1,%1;0:" : "=d" (mask),"=g" (addr) : "0" (mask),"1" (addr)); } } static void draw_vline(short x, short y1, short y2, short color) { unsigned char *addr = buffer + (y1 << 5) - (y1 << 1) + (x >> 3); unsigned char mask = 0x80 >> (x & 7); while (y1++ <= y2) { if (color & C_INVERSE) { *addr ^= mask; *(addr + buffer_diff) ^= mask; } else { if (color & 2) *addr |= mask; else *addr &= ~mask; if (color & 1) *(addr + buffer_diff) |= mask; else *(addr + buffer_diff) &= ~mask; } addr += 30; } } static void window(int w, int h) { short i; int x1 = (LCD_WIDTH - w) / 2; int x2 = x1 + w; int y1 = (LCD_HEIGHT - h) / 2; int y2 = y1 + h; penRow = y1 + 2; penCol = x1 + 2; draw_hline(x1, x2, y1, C_BLACK); draw_hline(x1, x2, y2, C_BLACK); draw_hline(x1 + 1, x2 + 1, y2 + 1, C_BLACK); for (i = y1 + 1; i < y2; i++) draw_hline(x1, x2, i, C_WHITE); draw_vline(x1, y1, y2, C_BLACK); draw_vline(x2, y1, y2, C_BLACK); draw_vline(x2 + 1, y1 + 1, y2 + 1, C_BLACK); } static void draw_char46(unsigned short a) { long addr = (long) ((char *) buffer + penRow*30 + (((penCol-4) >>3) & 0xfffe)); unsigned short cnt = 24-((penCol-4)&15), h = 6-1; long mask = ~(0x0FL << cnt); unsigned char *sprite = TextFont46 + (a /*- ' '*/) * 6; if (penCol == 0) addr = (long) ((char *) buffer + penRow*30 - 2); if (penColor & C_INVERSE) do { *(long *) addr &= mask; if (penColor & 2) *(long *) addr |= ((long)(~(*sprite)&0x0F)< 0) { sel_low = curs_ptr; sel_hi = gap_ptr+select; } else { sel_hi = curs_ptr; sel_low = sel_hi+select; } sprspc = TextFont46 + ' ' * 6; while (nb_row--) { scr_addr = scr_line; end_of_line = FALSE; for (cnt = 0; cnt < nb_col; cnt+=2) { if (end_of_line) { c1 = ' '; c2 = ' '; inv = 0; } else { inv = ( (sel_low <= stream_ptr) && (stream_ptr < sel_hi) ? 1 : 0); read_char(c1); if (c1 == LF || c1 == (EOF&0xFF)) { if (color_syntax) penColor = C_DARKGRAY; end_of_line = TRUE; c1 = ' '; c2 = ' '; inv = 0; } else { if (color_syntax) { if (!chartypes[c1]) penColor = C_DARKGRAY; else if (penColor == C_DARKGRAY) penColor = chartypes[c1] > 0 ? C_BLACK : C_LIGHTGRAY; } penColor1 = penColor; inv |= ( (sel_low <= stream_ptr) && (stream_ptr < sel_hi) ? 2 : 0); read_char(c2); if (c2 == LF || c2 == (EOF&0xFF)) { if (color_syntax) penColor = C_DARKGRAY; end_of_line = TRUE; c2 = ' '; } else if (color_syntax) { if (!chartypes[c2]) penColor = C_DARKGRAY; else if (penColor == C_DARKGRAY) penColor = chartypes[c2] > 0 ? C_BLACK : C_LIGHTGRAY; } } } //ADDED if(isDiese == 2) //Check previous stuff { if(c1 != '#' && c1 != '&') { penColor = C_BLACK; penColor1 = penColor; } isDiese = 0; }else if (isDiese == 1) { isDiese++; penColor1 = C_LIGHTGRAY; //POWA ! } if (c1 == '#' || c1 == '&') { isDiese = 2; penColor = C_LIGHTGRAY; //POWA ! penColor1 = C_LIGHTGRAY; } else if (c2 == '#' || c2 == '&') isDiese = 1; //ADDED spr1 = TextFont46 + (c1 /*- ' '*/) * 6; spr2 = TextFont46 + (c2 /*- ' '*/) * 6; spr11 = (penColor1 & 2) ? spr1 : sprspc; spr21 = (penColor & 2) ? spr2 : sprspc; spr12 = (penColor1 & 1) ? spr1 : sprspc; spr22 = (penColor & 1) ? spr2 : sprspc; addr = scr_addr++; *(addr) = 0; addr+=30; i = 6-1; switch (inv) { case 0: do { *addr = *(spr11++)<<4 | *(spr21++); *(addr + buffer_diff) = *(spr12++)<<4 | *(spr22++); addr += 30; } while (i--); break; case 1: do { *addr = (~*(spr11++))<<4 | *(spr21++); *(addr + buffer_diff) = (~*(spr12++))<<4 | *(spr22++); addr += 30; } while (i--); break; case 2: do { *addr = *(spr11++)<<4 | ((~*(spr21++)) & 0x0F); *(addr + buffer_diff) = *(spr12++)<<4 | ((~*(spr22++)) & 0x0F); addr += 30; } while (i--); break; default: do { *addr = ~(*(spr11++)<<4 | *(spr21++)); *(addr + buffer_diff) = ~(*(spr12++)<<4 | *(spr22++)); addr += 30; } while (i--); break; } if ((char*)addr < (char*)buffer + (LCD_HEIGHT - 8) * 30) *addr = *(addr + buffer_diff) = 0; } scr_line += 30 * 7; } } static void draw_str46(const char *str) { while (*str) draw_char46(*str++ & 0xFF); } static void draw_str_center46(const char *str) { penCol = (LCD_WIDTH - strlen(str) * 4) / 2; draw_str46(str); penRow += 8; } static void print_str(const char *format, ...) { va_list a; va_start(a, format); vcbprintf((vcbprintf_Callback_t) draw_char46, NULL, format, a); va_end(a); } static void prepare_bottom(void) { memset(buffer + (LCD_HEIGHT - 8) * 30, 0, 8 * 30); memset(buffer + buffer_diff + (LCD_HEIGHT - 8) * 30, 0, 8 * 30); memset(buffer + buffer_diff + (LCD_HEIGHT - 8) * 30, 0xff, 30); penCol = 0; penRow = LCD_HEIGHT - 7; penColor = C_DARKGRAY; } static void show_msg(const char *str) { prepare_bottom(); draw_str46(str); } static void draw_menu_bar(void) { short i; static const char *menu[] = { "Build", "Exec", "Goto", "Find", "Replace", "Config", "About" }; static const char *menu89[] = { "Bld", "Exe", "Goto", "Find", "Rplc", "Conf", "?" }; prepare_bottom(); for (i = 0; i < 7; i++) { print_str(Q("F%1d%s","F%1d %s"), i+1, Q(menu89,menu)[i]); penCol += 2; } refresh = TRUE; } static void update_indic(void) { unsigned short mod, xmod; short indic; static const unsigned char indic_spr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x11, 0x1D, 0x19, 0x17, 0x11, 0x04, 0x0E, 0x1F, 0x0E, 0x04, 0x00, 0x04, 0x0E, 0x1F, 0x0E, 0x0E, 0x00, 0x00, 0x06, 0x0A, 0x0A, 0x06, 0x00, 0x1F, 0x19, 0x15, 0x15, 0x19, 0x1F, 0x1F, 0x1B, 0x15, 0x11, 0x15, 0x15 }; mod = OSModKeyStatus; xmod = 1[&OSModKeyStatus]; if (mod & MOD_2ND) indic = I_SECOND; else if (mod & MOD_DIAMOND) indic = I_DIAMOND; else if (mod & MOD_SHIFT) indic = I_SHIFT; else if (mod & MOD_ALPHA) indic = I_ALPHA; else if (xmod & XMOD_CAPS) indic = I_CAPS; else if (xmod & XMOD_ALOCK) indic = I_ALOCK; else indic = I_NONE; if(indic != disp_indic) { const unsigned char *sprite = indic_spr + indic * 6; unsigned char *addr = buffer + LCD_WIDTH / 8 - 1; short h = 6; for ( ; h; h--, addr += 30) { *addr &= 0xE0; *addr |= *sprite; *(addr + buffer_diff) &= 0xE0; *(addr + buffer_diff) |= *sprite++; } disp_indic = indic; } } static unsigned short translate_key(unsigned short key) { key &= 0xF7FF; if (TI89) { unsigned short nkey = key & 0x9FFF; if (key & K_DIAMOND) nkey |= K_SHIFT; if (key & K_SHIFT) nkey |= K_DIAMOND; if (key == 16650) nkey = 95; key &= 0x0FFF; if (key == 337) nkey++; else if (key == 340) nkey += 4; else if (key == 344) nkey -= 4; else if (key == 338) nkey--; key = nkey; switch (key) { case K_DIAMOND|'/': return '!'; case K_DIAMOND|'*': return '&'; case K_DIAMOND|KEY_STO: return '@'; case K_DIAMOND|'0': return 156; /* <= */ case K_DIAMOND|'=': return 157; /* != */ case K_DIAMOND|'.': return 158; /* >= */ case K_DIAMOND|')': return 169; /* (C) */ } } if (key == KEY_STO) key = 22; return key; } static unsigned short get_key(void) { unsigned short key; void *kbq = kbd_queue(); OSTimerRestart(APD_TIMER); while (({pokeIO(0x600005,0b10111); OSdequeue(&key, kbq);})) { if (OSTimerExpired(APD_TIMER)) { off(); OSTimerRestart(APD_TIMER); continue; } update_indic(); } key = translate_key(key); if (key == K_DIAMOND + K_ON || key == K_OFF) off(); return key; } static error_t error(error_t state) { prepare_bottom(); if (state == ERR_MEMORY) draw_str46("Out of memory"); else if (state == ERR_EXEC) draw_str46("Cannot exec command."); else print_str("Error opening '%s'", filename); get_key(); draw_menu_bar(); return state; } static BOOL prompt(const char *str) { prepare_bottom(); print_str("%s [ENTER]=Yes [ESC]=No", str); return get_key() == K_ENTER; } static BOOL input_str(char *buf, short maxlen, short mode) { short key, i = strlen(buf); short col = penCol; do { buf[i] = 0; penCol = col; print_str("%s_ ", buf); key = get_key(); if (key == K_BACKSPACE && i) i--; if (i < maxlen && (isdigit(key) || (mode == INPUT_ALL && 32 <= key && key<=127) || (mode == INPUT_PATH && (isalnum(key) || key == '_' || key == '\\')))) buf[i++] = (mode == INPUT_PATH) ? tolower(key) : key; } while (((key != K_ENTER) || !i) && (key != K_ESC)); return key == K_ENTER; } static BOOL input_num(const char *prompt, int *num) { char buf[5]; BOOL ret; show_msg(prompt); buf[0] = 0; ret = input_str(buf, 4, INPUT_NUM); if (ret) *num = atol(buf); draw_menu_bar(); return ret; } static void draw_title_bar(void) { memset(buffer, 0, 8 * 30); memset(buffer + 6 * 30, 0xff, 30); memset(buffer + buffer_diff, 0, 6 * 30); memset(buffer + buffer_diff + 6*30, 0xff, 2 * 30); penColor = C_BLACK; penCol = penRow = 0; print_str("[S-IDE for u-view] file: %s", filename); disp_indic = I_NONE; } static void about(void) { window(112, 80); penRow += 2; penColor = C_BLACK; draw_str_center46("The Small Integrated"); draw_str_center46("Development Environment"); draw_str_center46("v0.1.P8 by Clem Vasseur"); draw_str_center46(""); draw_str_center46("Adapted by PpHd for PedroM"); draw_str_center46("Maintained by Kevin Kofler"); draw_str_center46(""); draw_str_center46("Modified by Pierre Nicolaz"); draw_str_center46(""); get_key(); draw_menu_bar(); } static void draw_str_config(const char *str1, short mode, void *val) { int col = penCol; short i; penColor = C_BLACK; draw_str46(str1); switch (mode) { case 0: draw_str46(*(BOOL *) val ? "Yes" : "No "); break; case 1: print_str("%3d", *(short *) val); break; default: draw_str46((char *) val); for (i = strlen(val); i < 26; i++) draw_char46(' '); } penRow += 8; penCol = col; } static void config(void) { int row, col, mod; short key, cursor = 0; char buf[28]; show_msg("[UP]/[DOWN]=Move [LEFT]/[RIGHT]=Change"); window(150+8, 54+6); row = penRow + 2; col = penCol; do { penRow = row; penCol = col; draw_str_config(" Build: ", 2, exec_name); draw_str_config(" Exec : ", 2, exec_name2); draw_str_config(" 2nd Text: ", 2, text2_name); draw_str_config(" Auto insert brackets: ", 0, &auto_code); draw_str_config(" Auto indent: ", 0, &auto_indent); draw_str_config(" Key repeat delay: ", 1, &key_delay); draw_str_config(" Key repeat rate: ", 1, &key_rate); penRow = row + cursor*8; penCol += 2; draw_char46('>'); mod = 0; switch (key = get_key()) { case K_RIGHT: mod = 1; break; case K_LEFT: mod = -1; break; case K_UP: if (cursor) cursor--; break; case K_DOWN: if (cursor < 6) cursor++; } if (mod) { switch (cursor) { case 0: penCol -= 4; draw_char46(' '); penCol += 42-4*3; memcpy(buf, exec_name, 26); if (input_str(buf, 25, INPUT_ALL)) memcpy(exec_name, buf, 26); break; case 1: penCol -= 4; draw_char46(' '); penCol += 42-4*3; memcpy(buf, exec_name2, 26); if (input_str(buf, 25, INPUT_ALL)) memcpy(exec_name2, buf, 26); break; case 2: penCol -= 4; draw_char46(' '); penCol += 42; memcpy(buf, text2_name, 18); if (input_str(buf, 17, INPUT_PATH)) { memcpy(text2_name, buf, 18); text2_pos = 5; } break; case 3: auto_code ^= 1; break; case 4: auto_indent ^= 1; break; case 5: mod = key_delay + mod * 10; if (mod > 0 && mod < 400) OSInitKeyInitDelay(key_delay = mod); break; default: mod += key_rate; if(mod > 0 && mod < 50) OSInitBetweenKeyDelay(key_rate = mod); } } } while (key != K_ENTER && key != K_ESC); draw_menu_bar(); } static void forget_selection(void) { if (select != 0) { select = 0; refresh = TRUE; } } static void move_right(void) { forget_selection(); if (*gap_ptr == EOF) return; curCol += 4; if (*gap_ptr == LF || curCol >= LCD_WIDTH) { if (*gap_ptr == LF) line++; curCol = 0; curRow += 7; if (curRow >= LCD_HEIGHT-8) { short col = LCD_WIDTH; curRow -= 7; while (col > 0 && *page_ptr++ != LF) col -= 4; refresh = TRUE; } } *curs_ptr++ = *gap_ptr++; } static void move_left(void) { forget_selection(); if (curs_ptr == file_ptr) return; *--gap_ptr = *--curs_ptr; curCol -= 4; if (*gap_ptr == LF || curCol < 0) { short col = 0; if (*gap_ptr == LF) line--; while ((curs_ptr - col) != file_ptr && *(curs_ptr - col - 1) != LF) col++; curCol = (col * 4) % LCD_WIDTH; curRow -= 7; if (curRow < 8) { curRow += 7; page_ptr = curs_ptr - (curCol / 4); refresh = TRUE; } } } static void move_down(void) { int curCol_save = curCol; BOOL allow_cr = TRUE; do { move_right(); if (!curCol) allow_cr = FALSE; } while (*gap_ptr != EOF && (allow_cr || ((*gap_ptr != LF) && (curCol < curCol_save)))); } static void move_up(void) { int curCol_save = curCol; BOOL allow_cr = TRUE; do { if (!curCol) allow_cr = FALSE; move_left(); } while (curs_ptr != file_ptr && (allow_cr || (curCol > curCol_save))); } static void move_right_word(void) { while (*gap_ptr != EOF && *gap_ptr != ' ' && *gap_ptr != LF) move_right(); while (*gap_ptr != EOF && (*gap_ptr == ' ' || *gap_ptr == LF)) move_right(); } static void move_left_word(void) { do { move_left(); } while (curs_ptr != file_ptr && (*gap_ptr == ' ' || *gap_ptr == LF)); while (curs_ptr != file_ptr && *gap_ptr != ' ' && *gap_ptr != LF) move_left(); if (curs_ptr != file_ptr) move_right(); } static BOOL clear_selection(void); static void del(void) { if (clear_selection() || *gap_ptr == EOF) return; gap_ptr++; modified = 1; refresh = TRUE; } static void back(void) { if (clear_selection() || curs_ptr == file_ptr) return; move_left(); del(); } static BOOL clear_selection(void) { short cnt = select; forget_selection(); if (cnt > 0) while (cnt--) del(); else if (cnt < 0) while (cnt++) back(); return cnt; } static error_t write(short c) { clear_selection(); if (curs_ptr + 2 >= gap_ptr) { char *ptr; long ptr_diff; if ((ptr = realloc(file_ptr, end_ptr - file_ptr + 1 + BUF_SIZE))) { ptr_diff = ptr - file_ptr; file_ptr = ptr; page_ptr += ptr_diff; curs_ptr += ptr_diff; gap_ptr += ptr_diff; end_ptr += ptr_diff; gap_ptr = memmove(gap_ptr + BUF_SIZE, gap_ptr, end_ptr - gap_ptr + 1); end_ptr += BUF_SIZE; } else return error(ERR_MEMORY); } *--gap_ptr = c; move_right(); modified = 1; refresh = TRUE; if (!auto_code) return ERR_NONE; if (c == '(') c = ')'; else if (c == '[') c = ']'; else if (c == '{') c = '}'; else if (c == '\'' || c == '\"'); else return ERR_NONE; *--gap_ptr = c; return ERR_NONE; } static void clear_line(void) { if (!clear_selection()) while (*gap_ptr != LF && *gap_ptr != EOF) del(); } static void line_start(void) { forget_selection(); while (curs_ptr != file_ptr && *(curs_ptr - 1) != LF) move_left(); } static void line_end(void) { forget_selection(); while (*gap_ptr != EOF && *gap_ptr != LF) move_right(); } static void page_top(void) { forget_selection(); while (curs_ptr != file_ptr) move_up(); } static void page_end(void) { forget_selection(); while (*gap_ptr != EOF) move_down(); } static void page_up(void) { short i = (LCD_HEIGHT - 16) / 7; while (i--) move_up(); } static void page_down(void) { short i = (LCD_HEIGHT - 16) / 7; while (i--) move_down(); } static void select_proc(void (*proc)(void)) { short sel = select; char *ptr = curs_ptr; proc(); select = sel + ptr - curs_ptr; refresh = TRUE; } static void select_right(void) { select_proc(move_right); } static void select_left(void) { select_proc(move_left); } static void select_up(void) { select_proc(move_up); } static void select_down(void) { select_proc(move_down); } static void go_line(void) { int target_line = target_line; if (!input_num("Goto line: ", &target_line)) return; if (!target_line) target_line++; if (line > target_line) while (line > target_line) move_up(); else while (line < target_line && *gap_ptr != EOF) move_down(); } static error_t clipboard_copy(void) { short cnt; char *stream_ptr; if (!select) return ERR_NONE; if (select > 0) { cnt = select; stream_ptr = gap_ptr; } else { cnt = -select; stream_ptr = curs_ptr - cnt; } if (CB_replaceTEXT(stream_ptr, cnt, FALSE)) return ERR_NONE; return error(ERR_MEMORY); } static void clipboard_paste(void) { HANDLE clipboard; size_t len; char *buf; BOOL auto_code_saved = auto_code; if (!CB_fetchTEXT(&clipboard, &len)) return; auto_code = FALSE; buf = HLock(clipboard); while (len-- && *buf != EOF && write(*buf++) == ERR_NONE); HeapUnlock(clipboard); auto_code = auto_code_saved; } static void find(void) { int find_str_len; show_msg("Find: "); if (input_str(find_str, 31, INPUT_ALL)) { find_str_len = strlen(find_str); do move_right(); while (*gap_ptr != EOF && strncmp(gap_ptr, find_str, find_str_len)); } draw_menu_bar(); } static void replace(void) { const char *a; int doit = 1, key, find_str_len; show_msg("Replace: "); if (input_str(find_str, 31, INPUT_ALL)) { show_msg("By: "); if (input_str(replace_str, 31, INPUT_ALL)) { find_str_len = strlen(find_str); while (*gap_ptr != EOF && doit) { // Find it do move_right(); while (*gap_ptr != EOF && strncmp(gap_ptr, find_str, find_str_len)); if (*gap_ptr != EOF) { a = find_str; while (*a++) select_right(); draw_text_screen((LCD_HEIGHT - 16)/7, LCD_WIDTH / 4, page_ptr); show_msg("Replace [ENTER], Next [F1], All [F5], Cancel [ESC]"); if (doit == 1) key = get_key(); else key = K_ENTER; switch (key) { case K_F5: doit = 2; case K_ENTER: del(); a = replace_str; while (*a) write(*a++); break; case K_ESC: doit = 0; default: break; } } } } } draw_menu_bar(); } #define FS_OK 0 #define SYM_LEN 8 #define MAX_SYM_LEN (4 + (SYM_LEN) * 2) //DEBUG #include static error_t open_file(void) { SYM_ENTRY *sym; char sym_buf[MAX_SYM_LEN]; char *sym_buf_ptr = sym_buf + MAX_SYM_LEN-1; size_t size; short *sptr = NULL; char *ptr; char *realval = malloc(LineMax); //MODIFIED if(filename[0] == '\\') //If true, active multidirectory mode { FILE *fsys; char *mounted = ((char*)(FILE_SYSTEM)); char *buf = malloc(LineMax); char *final; long buf; unsigned short isDiscovered = 0; //First we look for the file system config file fsys = fopen(mounted, "r+"); if(!fsys) return error(ERR_FILE); //Get each line, one by one and wheck if it does correspond to filename //rewind(fsys); while(fgets(buf, LineMax, fsys)) { isDiscovered = 2; //If !isDiscovered, file will be empty if(buf[strspn(buf, filename)] == FileDelimiter) //If filename found, exit of the loop { isDiscovered = 1; break; } if(feof(fsys)) break; } //rewind(fsys); if(isDiscovered) { buf[strcspn(buf, "\n")] = '\0'; //Delete new line character for more safety strtok(buf, CFileDelimiter); realval = strtok(NULL, CFileDelimiter); } if(!isDiscovered) //File empty { //Fill the file final = malloc(strlen(filename)+3); realval = ((char*)("a0")); sprintf(final, "%s%s%s\n", filename, CFileDelimiter, realval); final[strcspn(final, "\n")+1] = '\0'; if(fputs(final, fsys) == EOF) return error(ERR_FILE); } if(isDiscovered == 2) //File def not found { memmove(realval + 0, realval + 0 + 1, strlen(realval + 0 + 1) + 1); short b = atoi(realval); b++; final = malloc(strlen(filename)+strlen(realval)+3); sprintf(final, "%s%sa%u\n", filename, CFileDelimiter, b); final[strcspn(final, "\n")+1] = '\0'; if(fputs(final, fsys) == EOF) return error(ERR_FILE); sprintf(realval, "a%u", b); } fclose(fsys); free(buf); sprintf(filename, "sidetext\\%s\n", realval); //finally we set up the value filename[strcspn(filename, "\n")] = '\0'; } //MODFIFIED if (TokenizeName(filename, sym_buf) != FS_OK) return error(ERR_FILE); if ((sym = SymFindPtr(sym_buf_ptr, 0))) { if (*(unsigned char *) HToESI(sym->handle) != TEXT_TAG || sym->flags.bits.in_view == 1) return error(ERR_FILE); sym->flags.bits.in_view = 1; sptr = HeapDeref(sym->handle); size = *sptr - 5; sptr += 2; ptr = (char *) sptr; if (!(file_ptr = malloc(size + BUF_SIZE + 1))) return error(ERR_MEMORY); page_ptr = curs_ptr = file_ptr; end_ptr = gap_ptr = file_ptr + BUF_SIZE; while (*++ptr) if (*ptr == CR) { *end_ptr++ = LF; ptr++; } else *end_ptr++ = *ptr; } else if (DerefSym(SymAdd(sym_buf_ptr))) { SymDel(sym_buf_ptr); if (!(file_ptr = malloc(BUF_SIZE + 1))) return error(ERR_MEMORY); page_ptr = curs_ptr = file_ptr; end_ptr = gap_ptr = file_ptr + BUF_SIZE; } else return error(ERR_FILE); *end_ptr = EOF; line = 1; modified = FALSE; curCol = select = 0; curRow = 8; if (sptr) { sptr--; size = 1; while ((short)(curs_ptr - file_ptr + size) < *sptr) { if (*gap_ptr == LF) size++; move_right(); } } return ERR_NONE; } static error_t unuse_file(void) { SYM_ENTRY *sym; char sym_buf[MAX_SYM_LEN]; if (TokenizeName(filename, sym_buf) != FS_OK) return ERR_FILE; if (!(sym = SymFindPtr(sym_buf + MAX_SYM_LEN - 1, 0))) return ERR_FILE; sym->flags.bits.in_view = 0; return ERR_NONE; } static error_t save_file(void) { BOOL archived; SYM_ENTRY *sym; HANDLE handle; char sym_buf[MAX_SYM_LEN]; char *sym_buf_ptr = sym_buf + MAX_SYM_LEN - 1; char *src, *ptr = NULL; size_t size = curs_ptr - file_ptr + end_ptr - gap_ptr + 7; size_t curs_size = 1; if (!modified) return ERR_NONE; if (TokenizeName(filename, sym_buf) != FS_OK) return error(ERR_FILE); if (!(sym = SymFindPtr(sym_buf_ptr, 0)) && !(sym = DerefSym(SymAdd(sym_buf_ptr)))) return error(ERR_FILE); if ((archived = sym->flags.bits.archived)) if (!EM_moveSymFromExtMem(sym_buf_ptr, HS_NULL)) return error(ERR_MEMORY); for (src = file_ptr; src < end_ptr; src++) { if (src == curs_ptr) src = gap_ptr; if (*src == LF) { size++; if (src < curs_ptr) curs_size++; } } HeapUnlock(sym->handle); if ((handle = HeapRealloc(sym->handle, size))) { sym->handle = handle; ptr = HeapDeref(handle); *(short *) ptr = size-2; ptr += 2; *(short *) ptr = curs_ptr - file_ptr + curs_size; ptr += 2; *ptr++ = 0x20; for (src = file_ptr; src < end_ptr; src++) { if (src == curs_ptr) src = gap_ptr; if (*src == LF) { *ptr++ = '\r'; *ptr++ = 0x20; } else if (*src != EOF) *ptr++ = *src; } *ptr++ = 0x00; *ptr++ = 0xE0; } if (archived) { //pushkey(K_ENTER); EM_moveSymToExtMem(sym_buf_ptr, HS_NULL); //GKeyFlush(); } if (!ptr) return error(ERR_MEMORY); modified = 0; return ERR_NONE; } static void chars_table(void) { short i, j, key; short c_col = 0, c_row = 0; short col, row; show_msg("[ARROWS]=Move [ENTER]=Copy [ESC]=Exit"); /* 24 x 10 */ window(24 * 5 + 3, 10 * 8 + 2); col = penCol; row = penRow; do { penRow = row; for (i = 0; i < 10; i++) { penCol = col; for (j = 0; j < 24; j++) { penColor = C_BLACK; if (i == c_row && j == c_col) penColor += C_INVERSE; draw_char46(16 + i * 24 + j); penCol++; } penRow += 8; } switch (key = get_key()) { case K_RIGHT: c_col = (c_col + 1) % 24; break; case K_LEFT: c_col = ((--c_col) < 0 ? 23 : c_col); break; case K_UP: c_row = ((--c_row) < 0 ? 9 : c_row); break; case K_DOWN: c_row = (c_row + 1) % 10; break; case K_ENTER: write(16 + c_row * 24 + c_col); } } while (key != K_ENTER && key != K_ESC); draw_menu_bar(); } void launch(void *cptroff asm("a3"), unsigned long *percatcherpc asm("a2")); asm(" | LAUNCH DECOMPRESSED PROGRAM | NOTE: Some of this code is the same as in ttstart. This is | because this is code _I_ contributed to ttstart. So | it is being relicensed by the original author. .section .text.launch,\"x\" launch: movem.l %d1-%d7/%a0-%a6,-(%sp) moveq.l #0,%d6 move.w (%a3)+,%d6 | Round the length up to an even size | NOTE: The handle size is rounded up automatically. addq.l #1,%d6 moveq.l #0xfffffffe,%d0 and.l %d0,%d6 | Save error catcher PC lea.l ercatcherpc(%pc),%a0 move.l (%a2),(%a0) | Set new error catcher PC lea.l 0(%a3,%d6.l),%a0 lea.l (ercatcher-middle)(%a0),%a1 move.l %a1,(%a2) | Append the stub to the program lea.l middle(%pc),%a1 moveq.l #50,%d0 stub_copy_loop: move.w (%a1)+,(%a0)+ dbra.w %d0,stub_copy_loop | Unprotect and run the program pea target(%PC) movea.l %a3,%a4 pea (%a3,%d6.l) jbra unprotect_a3_jumpto_a4 target: | Clean up lea (%sp,36),%sp move.l (%sp)+,%d0 movem.l (%sp)+,%d1-%d7/%a0-%a6 rts | CODE EXECUTED AT END OF PROGRAM | NOTE: This is the same code as in ttstart, because the code in ttstart | is actually MY code. middle: nop nop nop | Unprotect and jump to the launcher movea.l (%sp)+,%a4 lea __ld_entry_point-target(%a4),%a3 move.l %d0,16(%sp) | Unprotection routine unprotect_a3_jumpto_a4: cmp.l #0x40000,%a3 bcs 0f lea.l 0x3f000,%a3 0: lea (%sp,-20),%sp move.l 0xc8.w,%d0 andi.l #0xE00000,%d0 addi.l #0x20000,%d0 move.l %d0,(%sp,12) move.l %d0,(%sp,16) move.l 20(%sp),(%sp) move.l 24(%sp),4(%sp) trap #0xC move.w #0x2700,%sr moveq.l #0xF,%d3 pea (%a4) clr.w -(%sp) move.l 0xAC,%a0 jmp (%a0) ercatcherentrypoint: .long __ld_entry_point ercatcherpc: .long 0 .even ercatcher: movem.l %d0-%d7/%a0-%a6,-(%sp) move.l ercatcherentrypoint(%PC),%a3 lea.l ercatchercleanup-__ld_entry_point(%a3),%a4 jbra unprotect_a3_jumpto_a4 | LAUNCHING CLEANUP CODE EXECUTED IN THE LAUNCHER'S EXECUTION SPACE ercatchercleanup: lea (%sp,20),%sp movem.l (%sp)+,%d0-%d7/%a0-%a6 move.l ercatcherpc(%PC),-(%a7) rts "); static void compile(const char name[]) { char cmd[64]; char *dest; const char *src, *f; if (save_file() != ERR_NONE) return; dest = cmd; *(dest++) = 0; for(src = name ; *src ; src++) if (*src == '!') for( f = filename ; *f ; f++) *(dest++) = *f; else *(dest++) = *src; *dest = 0; dest = strchr(cmd + 1, '('); if (!dest) {error(ERR_EXEC); return;} *dest = 0; SYM_ENTRY *sym = SymFindPtr(dest, 0); if (!sym) error(ERR_EXEC); else { HANDLE handle = sym->handle; if (!handle) error(ERR_EXEC); else { ESI old_estack = top_estack; *dest = '{'; *(dest + strlen(dest) - 1) = '}'; TRY push_parse_text(dest); top_estack--; ONERR push_END_TAG(); error(ERR_EXEC); ENDTRY int lock = HeapGetLock(handle); void *fptr = HLock(handle); HANDLE ch = HeapAllocHigh(*(unsigned short*)fptr+120); if (!ch) error(ERR_EXEC); else { void *cptr = HeapDeref(ch); char *p=p; void *oldlastexec; memcpy(cptr, fptr, *(unsigned short*)fptr + 2); unsigned long offset = (~*(long*)0xc8 & 0x800000) >> 5; TRY EX_patch(cptr + offset + 2, cptr + offset + *(unsigned short*)cptr + 1); ONERR error(ERR_EXEC); ER_success(); goto error; ENDTRY { /* rb and q are factored out in order to get more efficient code. */ char *rb=ROM_base; p=rb+0x12000; char *q=rb+0x18000; while (pPC); FINALLY GrayOn(); SetIntVec(TRAP_0,trap_0_hook); SetIntVec(TRAP_4,trap_4_hook); ENDFINAL ONERR error(ERR_EXEC); ENDTRY *(void **)(long)*(short *)p = oldlastexec; } error: top_estack = old_estack; HeapFree(ch); } if (!lock) HeapUnlock(handle); } } PortSet(buffer, 239, 127); refresh = TRUE; draw_menu_bar(); } static void show_text2(void) { char *ptr; int lock; short key; char buff_name[20]; SYM_ENTRY *sym = SymFindPtr(StrToTokN(text2_name, buff_name),0); if (sym == NULL) return; show_msg("[UP]/[DOWN]=Scroll [ESC]or[APPS]=Exit"); lock = HeapGetLock(sym->handle); ptr = HLock(sym->handle) + 4; do { draw_text_screen((LCD_HEIGHT - 16) / 7, LCD_WIDTH / 4, ptr + text2_pos); key = get_key(); if (key == K_DOWN) { key = LCD_WIDTH / 4; while (key-- && ptr[text2_pos] && ptr[++text2_pos - 2] != '\r'); key = ptr[text2_pos] ? 0 : K_UP; } if (key == K_UP) { key = LCD_WIDTH / 4; while (key-- && text2_pos > 5 && ptr[--text2_pos - 2] != '\r'); } } while (key != K_APPS && key != K_ESC); if (!lock) HeapUnlock(sym->handle); refresh = TRUE; draw_menu_bar(); } static void write_cr(void) { short nb_spaces = 0; char *ptr = curs_ptr; write(LF); if (!auto_indent) return; while (ptr != file_ptr && *--ptr != LF) if (*ptr == ' ') nb_spaces++; else nb_spaces = 0; while (nb_spaces--) write(' '); } CALLBACK void EventHandler(EVENT *ev) { switch (ev->Type) { case CM_NULL: case CM_WPAINT: case CM_KEY_PRESS: penRow = 0; penCol = LCD_WIDTH - 24; penColor = C_BLACK; print_str("%4d", line); if (refresh) draw_text_screen((LCD_HEIGHT - 16)/7, LCD_WIDTH / 4, page_ptr); refresh = FALSE; update_indic(); if (ev->Type == CM_KEY_PRESS) { unsigned short key = translate_key(ev->extra.Key.Code); draw_vline(curCol, curRow, curRow+6, C_WHITE); if (16 <= key && key <= 255) write(key); else if (key == K_COPY) clipboard_copy(); else if (key == K_PASTE) clipboard_paste(); else if (key == K_CUT && clipboard_copy() == ERR_NONE) clear_selection(); else switch (key) { case K_LEFT: move_left(); break; case K_RIGHT: move_right(); break; case K_UP: move_up(); break; case K_DOWN: move_down(); break; case K_SECOND+K_LEFT: line_start(); break; case K_SECOND+K_RIGHT: line_end(); break; case K_SECOND+K_UP: page_up(); break; case K_SECOND+K_DOWN: page_down(); break; case K_SHIFT+K_LEFT: select_left(); break; case K_SHIFT+K_RIGHT: select_right(); break; case K_SHIFT+K_UP: select_up(); break; case K_SHIFT+K_DOWN: select_down(); break; case K_DIAMOND+K_UP: page_top(); break; case K_DIAMOND+K_DOWN: page_end(); break; case K_DIAMOND+K_LEFT: move_left_word(); break; case K_DIAMOND+K_RIGHT: move_right_word(); break; case K_BACKSPACE: back(); break; case K_DIAMOND+K_BACKSPACE: del(); break; case K_ENTER: write_cr(); break; case K_CLEAR: clear_line(); break; case K_CHAR: chars_table(); break; case K_APPS: show_text2(); break; case K_F1: compile(exec_name); break; case K_F2: compile(exec_name2); break; case K_F3: go_line(); break; case K_F4: find(); break; case K_F5: replace(); break; case K_F6: config(); break; case K_F7: about(); break; case K_OFF: case K_DIAMOND+K_ON: off(); break; case K_ESC: ER_throw(ER_STOP); case K_QUIT: ER_throw(ER_PRGM_STOP); default: EV_defaultHandler(ev); break; } draw_vline(curCol, curRow, curRow+6, C_BLACK); } break; case CM_STO: case CM_PASTE_STRING: case CM_PASTE_HANDLE: EV_defaultHandler(ev); break; case CM_QUIT: ER_throw(ER_PRGM_STOP); break; case CM_CURSOR_FLASH: draw_vline(curCol, curRow, curRow+6, C_BLACK + C_INVERSE); break; } } void run_side(void) { char filebuffer[28]; volatile unsigned short err; filename = malloc(LineMax); if (filename) strcpy(filebuffer,filename); else filebuffer[0] = '\0'; filename = filebuffer; while (err != ER_PRGM_STOP) { memset(buffer, 0, LCD_SIZE); memset(buffer + buffer_diff, 0, LCD_SIZE); draw_title_bar(); if (filebuffer[0] == 0) { show_msg("Filename: "); if (!input_str(filebuffer, LineMax, INPUT_PATH)) return; draw_title_bar(); } show_msg("Loading ..."); if (open_file() != ERR_NONE) return; draw_menu_bar(); refresh = TRUE; short cursorState = CU_start(); volatile EVENT_HANDLER old_handler = EV_captureEvents(EventHandler); do { TRY EV_eventLoop(); ONERR EV_captureEvents(old_handler); err=errCode; if (errCode != ER_STOP && errCode != ER_PRGM_STOP) ERD_dialog(errCode,FALSE); ENDTRY } while (err != ER_STOP && err != ER_PRGM_STOP); CU_restore(cursorState); if (modified && prompt("Save changes?")) { memset(buffer + 30 * 8, 0, 30 * (LCD_HEIGHT - 16)); memset(buffer + 30 * 8 + buffer_diff, 0, 30 * (LCD_HEIGHT - 16)); save_file(); } unuse_file(); free(file_ptr); filebuffer[0] = '\0'; err = ER_PRGM_STOP; } } extern unsigned short idle_offset; asm(" .section .text.trap_0_hook_impl,\"x\" trap_0_hook_impl: .word 0x0c40 | cmpi.w #imm,%d0 idle_offset: .word 0 jbeq 0f .word 0x4ef9 | jmp abs.l old_trap_0: .long 0 0: | override idle to work with grayscale move.b #0b10111,0x600005 rte "); void _main(void) { short save_key_delay; short save_key_rate; ESI argptr = top_estack; init_side(); if (ArgCount() == 1 && GetArgType(argptr) == STR_TAG) filename = ((char*)(GetStrnArg(argptr))); else filename = NULL; save_key_delay = OSInitKeyInitDelay(key_delay); save_key_rate = OSInitBetweenKeyDelay(key_rate); GrayOn(); idle_offset = 1[(unsigned short *)idle]; old_trap_0 = GetIntVec(TRAP_0); SetIntVec(TRAP_0,trap_0_hook); old_trap_4 = GetIntVec(TRAP_4); SetIntVec(TRAP_4,trap_4_hook); buffer = __D_plane; buffer_diff = __L_plane-__D_plane; PortSet(buffer, 239, 127); unsigned char *flag; flag = (unsigned char *) &ST_flags; flag++; *flag &= ~(1 << 4); run_side(); *flag |= 1<<4; SetIntVec(TRAP_4,old_trap_4); SetIntVec(TRAP_0,old_trap_0); GrayOff(); OSInitKeyInitDelay(save_key_delay); OSInitBetweenKeyDelay(save_key_rate); }