fl { The Tiny Forth Editor Project is work in progress. Note the demo is still a single line editor. At this stage the target is the Ramblade but a simple API should make it easily ported to any Propboard with access to Xmem. All tests to date have been on a Ramblade board. (Drivers for Ramblade form part of this file) This file now includes additional words to run a virtual Tiny Editor in xmem. Text from the edbuf start, to the current cursor position are saved to xmem. Text right of the cursor, if any, is relocated to the start of the edbuf(see realign). Then new space is created in xmem to accomodate the next line if not at eof. Otherwise the new line will simply be appended. UP arrow will fetch the previous from xmem to edbuf. Down arrow will fetch next line from xmem if not eof. ANSI Escape Sequences to support the demo forms part of this File. The code relies on REV 4.00 core words only, propforth.f is not required TODO Clean up code and move more vars to cog asmlabel Add support for multi line VT00. VGA terminal will use the same VT100 API Add support to save file from xmem to SD card It goes on.. Known issues 1 Word wrap not handled will hang on line overflow TOFIX } 40 wconstant col_max \ Max Cols, can be redifined 200 wconstant xmem_base \ define base xmadr for text file 5 wconstant offset \ used to sync terminal line no and xmem row adr 0017FFFF constant ram_dr \ reqd by xmem driver FF07FFFF constant ram_dw \ reqd by xmem driver FF37FFFF constant ram_strobe \ reqd by xmem driver 0003FFFF constant mem_top \ reqd by xmem driver wvariable s_adr \ source adr for xmem copy wvariable d_adr \ dest adr for xmem copy wvariable row \ adr of current row in xmem wvariable eof \ adr of last row in xmem wvariable edbuf col_max allot wvariable guardband 10 allot \ provision for word wrap wvariable temp wvariable msFlag \ set to 0 if space for a newline required \ Xmem support for RamBlade : set_dira dira COG! ; : set_outa outa COG! ; : rd_ina ina COG@ ; : xrd dup 0 set_dira mem_top < if set_outa ram_dr set_dira rd_ina 18 rshift then ; : xwr dup 0 set_dira mem_top < if ram_dw set_dira swap 18 lshift or set_outa ram_strobe set_dira ram_dw set_dira then ; : xmv 0 do s_adr W@ i + xrd d_adr W@ i + xwr loop ; : xclr swap s_adr W! 0 do 20 s_adr W@ i + xwr loop ; : xdump swap s_adr W! \ my debug tool 0 do i 4 u/mod 4* i swap - 0= if cr then drop s_adr W@ i + dup xrd swap .addr space .word space space loop cr ; : xcp swap xrd swap xwr ; : dbug 200 200 xdump ; \ xmemory dump.....my debug tool \ End of Ramblade support : .digits dup 9 > if a u/mod 30 + emit then 30 + emit ; \ does not trap chr f > TOFIX) : at_cursor 1b emit 5b emit .digits ." ;" .digits ." f" ; \ set cursor, get col and row data from TOS : cls 1b emit 5b emit ." 2J" ; \ ANSI VT100 clear screen c" ptr" clabel \ asmlabel in current cog COG. Holds pointer to current col : g_ptr ptr COG@ ; \ push pointer : p_ptr ptr COG! ; \ pop to ptr : g_eof eof W@ ; \ push eof : p_eof eof W! ; \ pop to eof : g_row row W@ ; \ push row_ptr : p_row row W! ; \ pop to row_ptr : inc_eof g_eof col_max + p_eof ; \ inc eof adr by col_max : inc_ptr g_ptr 1 + p_ptr ; \ inc ptr (cog long) : dec_ptr g_ptr 1 - p_ptr ; \ dec ptr : inc_row g_row col_max + p_row ; \ inc xmem row adr : dec_row g_row col_max - p_row ; \ dec xmem row adr : clr_buffer col_max 0 do 20 edbuf i + C! loop ; \ clear buffer HUB : cln 0 5 at_cursor 40 0 do 20 emit loop 0 5 at_cursor ; : make_space g_eof g_row - col_max - temp W! g_eof d_adr W! begin d_adr W@ col_max - s_adr W! col_max xmv s_adr W@ d_adr W! temp W@ col_max - dup temp W! 0= until ; : mscheck msFlag W@ 0= if FF msFlag W! make_space else 0 msFlag W! then ; : realign col_max g_ptr - 0 do edbuf g_ptr + i + C@ edbuf i + C! loop col_max g_ptr - col_max swap - 0 do 20 edbuf col_max + g_ptr - i + C! loop ; : wrline g_ptr 0 do edbuf i + C@ g_row i + xwr loop dec_ptr col_max g_ptr - 0 do 20 g_row g_ptr + i + xwr loop ; : rdline col_max 1 - 0 do row W@ i + xrd edbuf i + C! loop ; : save_xmem g_eof g_row <> if mscheck then wrline realign inc_row inc_eof ; : col_max g_ptr - 0 do edbuf col_max + 1 - i - C@ edbuf col_max + i - C! loop ; : mvup g_row xmem_base > if dec_row clr_buffer rdline then ; : mvdown g_row g_eof < if inc_row clr_buffer rdline then ; { ~~~~~~~~~~~~~~~ ESC manager for arrow keys ~~~~~~~~~~~~~~~~~~~ A single arrow key generates 3 bytes. The first key stroke (any arrow key) will push 1B to TOS to release the next byte the key word is called again. If the byte is 5B another call to Key is used to decode the arrow key. So what would happens if an escape key pressed by itself leaving no other key in the input stream ? The process would hang until another character is recieved. Once a key is pressed it will be dropped and processing continues normally. The ESC manager will be extended later to provide additional functionality } : esc key dup 5B = if drop key dup 41 = if mvup else dup 42 = if mvdown else dup 43 = if inc_ptr else dup 44 = if dec_ptr then then then then then ; \ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now the DISPLAY CODE for DEMO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ : disp_ln 0 5 at_cursor edbuf col_max .str g_ptr 5 at_cursor ; : sv_chr dup d <> if edbuf g_ptr + C! else drop then ; : save_chr dup dup dup dup 0 <> if 8 = if g_ptr 0 > if sv_chr inc_ptr then then ; : keyin key dup 1B = if esc else save_chr then ; \ ~~~~~~~~~~~~~~~~~~~~~~~~~ MAIN LOOP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ : init_edit cls 10 0 at_cursor c" A Tiny Forth Text Editor TFTE_demo_0.01_04012011 by R. Sutcliffe " .cstr 200 400 xclr 0 msFlag W! xmem_base dup p_row p_eof clr_buffer begin 0 p_ptr disp_ln g_ptr 5 at_cursor begin keyin g_ptr col_max > if dec_ptr drop d else dup d <> if disp_ln drop then then d = until drop save_xmem cln 0 until ; \ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~