├── TECF.COM ├── TETX.COM ├── TE_KP.COM ├── TE_MUR.COM ├── TE_PCW.COM ├── TE_PX8.COM ├── TE_SAM.COM ├── TE_TAK.COM ├── TE_ANSI.COM ├── TE_APPLE.COM ├── TE_C128.COM ├── TE_CPC3.COM ├── TE_SPEC.COM ├── TE_WS100.COM ├── make_tecf.bat ├── make_tetx.bat ├── CDO.M ├── CFOR.M ├── CIF.M ├── CWHILE.M ├── make.bat ├── HEADER.M ├── JOINUP.M ├── JOINDOWN.M ├── make_all.bat ├── CIFELSE.M ├── CFUN.M ├── CSWITCH.M ├── CFILE.M ├── .gitignore ├── TE_ANSI.CF ├── TE_C128.CF ├── TE_SAM.CF ├── TE_KP.CF ├── TE_PCW.CF ├── TE_MUR.CF ├── TE_PX8.CF ├── TE_WS100.CF ├── TE_CPC3.CF ├── TE_SPEC.CF ├── TE_TAK.CF ├── TE_APPLE.CF ├── te_misc.c ├── te_error.c ├── TE.CF ├── te_keys.h ├── te_keys.c ├── te_c128.c ├── te_sam.c ├── te_apple.c ├── te_conf.c ├── te_px8.c ├── te_kp.c ├── te_pcw.c ├── te_mur.c ├── te_file.c ├── te_spec.c ├── te_cpc3.c ├── te_lines.c ├── te_ws100.c ├── te_tak.c ├── te.h ├── te_ansi.c ├── te_macro.c ├── tetx.c ├── te_edit.c ├── te_ui.c ├── copying.txt └── README.MD /TECF.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TECF.COM -------------------------------------------------------------------------------- /TETX.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TETX.COM -------------------------------------------------------------------------------- /TE_KP.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_KP.COM -------------------------------------------------------------------------------- /TE_MUR.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_MUR.COM -------------------------------------------------------------------------------- /TE_PCW.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_PCW.COM -------------------------------------------------------------------------------- /TE_PX8.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_PX8.COM -------------------------------------------------------------------------------- /TE_SAM.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_SAM.COM -------------------------------------------------------------------------------- /TE_TAK.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_TAK.COM -------------------------------------------------------------------------------- /TE_ANSI.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_ANSI.COM -------------------------------------------------------------------------------- /TE_APPLE.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_APPLE.COM -------------------------------------------------------------------------------- /TE_C128.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_C128.COM -------------------------------------------------------------------------------- /TE_CPC3.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_CPC3.COM -------------------------------------------------------------------------------- /TE_SPEC.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_SPEC.COM -------------------------------------------------------------------------------- /TE_WS100.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiguelVis/te/HEAD/TE_WS100.COM -------------------------------------------------------------------------------- /make_tecf.bat: -------------------------------------------------------------------------------- 1 | cpm cc tecf 2 | cpm ccopt tecf 3 | cpm zsm tecf 4 | cpm hextocom tecf 5 | 6 | del tecf.zsm 7 | del tecf.prn 8 | del tecf.hex 9 | -------------------------------------------------------------------------------- /make_tetx.bat: -------------------------------------------------------------------------------- 1 | cpm cc tetx 2 | cpm ccopt tetx 3 | cpm zsm tetx 4 | cpm hextocom tetx 5 | 6 | del tetx.zsm 7 | del tetx.prn 8 | del tetx.hex 9 | -------------------------------------------------------------------------------- /CDO.M: -------------------------------------------------------------------------------- 1 | {# C language snippet: do/while} 2 | {AutoIndent} 3 | do \{{NewLine} 4 | {Indent}{NewLine} 5 | {DelLeft:4}\} while(); 6 | {End}{Left:2} 7 |  -------------------------------------------------------------------------------- /CFOR.M: -------------------------------------------------------------------------------- 1 | {# C language snippet: for} 2 | {AutoIndent} 3 | for(;;) \{{NewLine} 4 | {Indent}{NewLine} 5 | {DelLeft:4}\} 6 | {Begin}{Up:2}{End}{Left:5} 7 |  -------------------------------------------------------------------------------- /CIF.M: -------------------------------------------------------------------------------- 1 | {# C language snippet: if} 2 | {AutoIndent} 3 | if() \{{NewLine} 4 | {Indent}{NewLine} 5 | {DelLeft:4}\} 6 | {Begin}{Up:2}{End}{Left:3} 7 |  -------------------------------------------------------------------------------- /CWHILE.M: -------------------------------------------------------------------------------- 1 | {# C language snippet: while} 2 | {AutoIndent} 3 | while() \{{NewLine} 4 | {Indent}{NewLine} 5 | {DelLeft:4}\} 6 | {Begin}{Up:2}{End}{Left:3} 7 | -------------------------------------------------------------------------------- /make.bat: -------------------------------------------------------------------------------- 1 | cpm cc %1 2 | cpm ccopt %1 3 | cpm zsm %1 4 | cpm hextocom %1 5 | 6 | cpm tecf PATCH %1.com %1.cf 7 | 8 | del %1.zsm 9 | del %1.prn 10 | del %1.hex 11 | -------------------------------------------------------------------------------- /HEADER.M: -------------------------------------------------------------------------------- 1 | {# example header} 2 | {top}{newline}{up} 3 | +----------------+{newline} 4 | | FloppySoftware |{newline} 5 | +----------------+{newline} 6 |  -------------------------------------------------------------------------------- /JOINUP.M: -------------------------------------------------------------------------------- 1 | {# join the previous line and current} 2 | {begin}{delleft} {end} 3 |  -------------------------------------------------------------------------------- /JOINDOWN.M: -------------------------------------------------------------------------------- 1 | {# join the current line and the next one} 2 | {end}{delright} {end} 3 |  -------------------------------------------------------------------------------- /make_all.bat: -------------------------------------------------------------------------------- 1 | call make te_cpc3 2 | call make te_kp 3 | call make te_mur 4 | call make te_pcw 5 | call make te_spec 6 | call make te_tak 7 | call make te_ws100 8 | call make te_ansi 9 | call make te_px8 10 | call make te_apple 11 | call make te_c128 12 | call make te_sam 13 | -------------------------------------------------------------------------------- /CIFELSE.M: -------------------------------------------------------------------------------- 1 | {# C language snippet: if/else} 2 | {AutoIndent} 3 | if() \{{NewLine} 4 | {Indent}{NewLine} 5 | {DelLeft:4}\}{NewLine} 6 | else \{{Newline} 7 | {Indent}{NewLine} 8 | {DelLeft:4}\} 9 | {Begin}{Up:5}{End}{Left:3} 10 |  -------------------------------------------------------------------------------- /CFUN.M: -------------------------------------------------------------------------------- 1 | {# docblock for a C function} 2 | {begin}{newline}{up} 3 | /**{newline} 4 | * @fn [prototype]{newline} 5 | * @brief [small explanation]{newline} 6 | * @param [name] - [meaning]{newline} 7 | * @return [what]{newline} 8 | */ 9 | {up:4} 10 | {right:8} 11 |  -------------------------------------------------------------------------------- /CSWITCH.M: -------------------------------------------------------------------------------- 1 | {# C language snippet: switch} 2 | {AutoIndent} 3 | switch() \{{NewLine} 4 | {Indent}case X :{NewLine} 5 | {Indent}break;{NewLine} 6 | {DelLeft:4}case X :{NewLine} 7 | {Indent}break;{NewLine} 8 | {DelLeft:4}default :{NewLine} 9 | {Indent}break;{NewLine} 10 | {DelLeft:8}\} 11 | {Begin}{Up:7}{End}{Left:3} 12 |  -------------------------------------------------------------------------------- /CFILE.M: -------------------------------------------------------------------------------- 1 | {# docblock for a C language file} 2 | {top}{newline}{up} 3 | /**{newline} 4 | * @file {filename}{newline} 5 | * @brief [small explanation]{newline} 6 | * @author Miguel I. Garcia Lopez / FloppySoftware{newline} 7 | *{newline} 8 | * This library implements [long explanation]{newline} 9 | *{newline} 10 | * Copyright (c) [year] Miguel I. Garcia Lopez / FloppySoftware{newline} 11 | *{newline} 12 | * Licensed under the GNU General Public License v3.{newline} 13 | *{newline} 14 | * http://www.floppysoftware.es{newline} 15 | * floppysoftware@gmail.com{newline} 16 | *{newline} 17 | * Definitions:{newline} 18 | * - [def]{newline} 19 | *{newline} 20 | * Revisions:{newline} 21 | * - [date] : [reason]{newline} 22 | *{newline} 23 | */{newline} 24 | {top}{down}{right:11} 25 |  -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # --------------------------- 2 | # MESCC & TOOL CHAIN BINARIES 3 | # --------------------------- 4 | cpm.exe 5 | cpm2.exe 6 | cpm_player.exe 7 | cc.com 8 | cc.COM 9 | CC.COM 10 | ccopt.com 11 | ccopt.COM 12 | CCOPT.COM 13 | zsm.com 14 | ZSM.COM 15 | hextocom.com 16 | hextocom.COM 17 | HEXTOCOM.COM 18 | link.com 19 | LINK.COM 20 | prntosym.com 21 | prntosym.COM 22 | PRNTOSYM.COM 23 | zmac.exe 24 | 25 | # --------------- 26 | # MESCC LIBRARIES 27 | # --------------- 28 | alloc.h 29 | atexit.h 30 | bsearch.h 31 | clock.h 32 | conio.h 33 | cpm.h 34 | ctype.h 35 | fileio.h 36 | fprintf.h 37 | mem.h 38 | mescc.h 39 | printf.h 40 | qsort.h 41 | rand.h 42 | redir.h 43 | setjmp.h 44 | sprintf.h 45 | stdbool.h 46 | string.h 47 | xprintf.h 48 | z80.h 49 | 50 | # ------------------ 51 | # INTERMEDIATE FILES 52 | # ------------------ 53 | *.HEX 54 | *.ZSM 55 | *.PRN 56 | 57 | # ----------------------- 58 | # PROJECT FILES & FOLDERS 59 | # ----------------------- 60 | backup/ 61 | cfreader.h 62 | TODO.TXT 63 | TE.BKP 64 | -------------------------------------------------------------------------------- /TE_ANSI.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # ANSI TERMINAL 4 | # ======================================== 5 | te.confName = "ANSI Terminal" 6 | 7 | screen.rows = 25 8 | screen.columns = 80 9 | 10 | screen.rulerChar = . 11 | screen.rulerTabChar = ! 12 | screen.vertChar = | 13 | screen.horizChar = - 14 | screen.lineNumbersChar = | 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = ENTER 25 | keyname.escape = ESC 26 | 27 | key.up = ^E 28 | key.down = ^X 29 | key.left = ^S 30 | key.right = ^D 31 | key.begin = ^V 32 | key.end = ^A 33 | key.top = ^P 34 | key.bottom = ^F 35 | key.pgUp = ^R 36 | key.pgDown = ^C 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^? 41 | key.delLeft = ^H 42 | key.cut = ^U 43 | key.copy = ^O 44 | key.paste = ^W 45 | key.delete = ^G 46 | key.clearClip = ^T 47 | key.find = ^K 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_C128.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # COMMODORE 128 4 | # ======================================== 5 | te.confName = "Commodore 128" 6 | 7 | screen.rows = 24 8 | screen.columns = 80 9 | 10 | screen.rulerChar = . 11 | screen.rulerTabChar = ! 12 | screen.vertChar = | 13 | screen.horizChar = - 14 | screen.lineNumbersChar = | 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = RETURN 25 | keyname.escape = ESC 26 | 27 | key.up = ^E 28 | key.down = ^X 29 | key.left = ^S 30 | key.right = ^D 31 | key.begin = ^A 32 | key.end = ^F 33 | key.top = ^O 34 | key.bottom = ^P 35 | key.pgUp = ^Q 36 | key.pgDown = ^Z 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^V 41 | key.delLeft = ^? 42 | key.cut = ^U 43 | key.copy = ^R 44 | key.paste = ^W 45 | key.delete = ^G 46 | key.clearClip = ^T 47 | key.find = ^K 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_SAM.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # SAM Coupe 4 | # ======================================== 5 | te.confName = "SAM Coupe" 6 | 7 | screen.rows = 24 8 | screen.columns = 80 9 | 10 | screen.rulerChar = . 11 | screen.rulerTabChar = ! 12 | screen.vertChar = | 13 | screen.horizChar = - 14 | screen.lineNumbersChar = | 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = RETURN 25 | keyname.escape = ESC 26 | 27 | key.up = ^_ 28 | key.down = ^^ 29 | key.left = ^\ 30 | key.right = ^] 31 | 32 | key.begin = ^Q 33 | key.end = ^E 34 | key.top = ^W 35 | key.bottom = ^Z 36 | key.pgUp = ^R 37 | key.pgDown = ^C 38 | key.indent = ^I 39 | key.newLine = ^M 40 | key.escape = ^[ 41 | key.delRight = ^H 42 | key.delLeft = ^? 43 | key.cut = ^U 44 | key.copy = ^O 45 | key.paste = ^P 46 | key.delete = ^D 47 | key.clearClip = ^T 48 | key.find = ^K 49 | key.findNext = ^L 50 | key.goLine = ^J 51 | #key.wordLeft = "" 52 | #key.wordRight = "" 53 | key.blockStart = ^BS 54 | key.blockEnd = ^BE 55 | key.blockUnset = ^BU 56 | key.macro = ^Y 57 |  -------------------------------------------------------------------------------- /TE_KP.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # KAYPRO II, 4, AND 10 4 | # ======================================== 5 | te.confName = "Kaypro II, 4, and 10" 6 | 7 | screen.rows = 24 8 | screen.columns = 80 9 | 10 | screen.rulerChar = . 11 | screen.rulerTabChar = ! 12 | screen.vertChar = | 13 | screen.horizChar = - 14 | screen.lineNumbersChar = | 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = RETURN 25 | keyname.escape = ESC 26 | 27 | key.up = ^K 28 | key.down = ^J 29 | key.left = ^H 30 | key.right = ^L 31 | key.begin = ^V 32 | key.end = ^\ 33 | key.top = ^P 34 | key.bottom = ^S 35 | key.pgUp = ^Q 36 | key.pgDown = ^Z 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^G 41 | key.delLeft = ^? 42 | key.cut = ^U 43 | key.copy = ^R 44 | key.paste = ^W 45 | key.delete = ^X 46 | key.clearClip = ^T 47 | key.find = ^F 48 | key.findNext = ^D 49 | key.goLine = ^A 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_PCW.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # AMSTRAD PCW 4 | # ======================================== 5 | te.confName = "Amstrad PCW" 6 | 7 | screen.rows = 31 8 | screen.columns = 90 9 | 10 | screen.rulerChar = 144 11 | screen.rulerTabChar = 145 12 | screen.vertChar = 149 13 | screen.horizChar = 154 14 | screen.lineNumbersChar = 149 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = RETURN 25 | keyname.escape = EXIT 26 | 27 | key.up = ^_ 28 | key.down = ^^ 29 | key.left = ^A 30 | key.right = ^F 31 | key.begin = ^V 32 | key.end = ^\ 33 | key.top = ^P 34 | key.bottom = ^S 35 | key.pgUp = ^Q 36 | key.pgDown = ^Z 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^G 41 | key.delLeft = ^? 42 | key.cut = ^U 43 | key.copy = ^R 44 | key.paste = ^W 45 | key.delete = ^D 46 | key.clearClip = ^T 47 | key.find = ^K 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_MUR.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # K. MURAKAMI'S CP/M EMULATOR 4 | # ======================================== 5 | te.confName = "K. Murakami's CP/M emulator" 6 | 7 | screen.rows = 25 8 | screen.columns = 80 9 | 10 | screen.rulerChar = . 11 | screen.rulerTabChar = ! 12 | screen.vertChar = | 13 | screen.horizChar = - 14 | screen.lineNumbersChar = | 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = ENTER 25 | keyname.escape = ESC 26 | 27 | key.up = ^E 28 | key.down = ^X 29 | key.left = ^S 30 | key.right = ^D 31 | key.begin = ^N 32 | key.end = ^A 33 | key.top = ^P 34 | key.bottom = ^F 35 | key.pgUp = ^R 36 | key.pgDown = ^C 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^? 41 | key.delLeft = ^H 42 | key.cut = ^U 43 | key.copy = ^O 44 | key.paste = ^W 45 | key.delete = ^G 46 | key.clearClip = ^T 47 | key.find = ^K 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_PX8.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # EPSON PX-8 'GENEVA' 4 | # ======================================== 5 | te.confName = "Epson PX-8 'Geneva'" 6 | 7 | screen.rows = 8 8 | screen.columns = 80 9 | 10 | screen.rulerChar = 144 11 | screen.rulerTabChar = 143 12 | screen.vertChar = 149 13 | screen.horizChar = 133 14 | screen.lineNumbersChar = 149 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = RETURN 25 | keyname.escape = ESC 26 | 27 | key.up = ^^ 28 | key.down = ^_ 29 | key.left = ^] 30 | key.right = ^\ 31 | key.begin = ^N 32 | key.end = ^A 33 | key.top = ^P 34 | key.bottom = ^F 35 | key.pgUp = ^R 36 | key.pgDown = ^D 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^? 41 | key.delLeft = ^H 42 | key.cut = ^X 43 | key.copy = ^C 44 | key.paste = ^V 45 | key.delete = ^G 46 | key.clearClip = ^T 47 | key.find = ^K 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_WS100.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # VT100 & WORDSTAR KEYS 4 | # ======================================== 5 | te.confName = "VT100 & WordStar keys" 6 | 7 | screen.rows = 25 8 | screen.columns = 80 9 | 10 | screen.rulerChar = . 11 | screen.rulerTabChar = ! 12 | screen.vertChar = | 13 | screen.horizChar = - 14 | screen.lineNumbersChar = | 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = ENTER 25 | keyname.escape = ESC 26 | 27 | key.up = ^E 28 | key.down = ^X 29 | key.left = ^S 30 | key.right = ^D 31 | key.begin = ^QS 32 | key.end = ^QD 33 | key.top = ^QR 34 | key.bottom = ^QC 35 | key.pgUp = ^R 36 | key.pgDown = ^C 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^G 41 | key.delLeft = ^H 42 | key.cut = ^Y 43 | key.copy = ^O 44 | key.paste = ^W 45 | key.delete = ^KY 46 | key.clearClip = ^T 47 | key.find = ^QF 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | key.wordLeft = ^A 51 | key.wordRight = ^F 52 | key.blockStart = ^KB 53 | key.blockEnd = ^KK 54 | key.blockUnset = ^KU 55 | key.macro = ^QM 56 |  -------------------------------------------------------------------------------- /TE_CPC3.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # AMSTRAD CPC & CP/M PLUS 4 | # ======================================== 5 | te.confName = "Amstrad CPC & CP/M 3" 6 | 7 | screen.rows = 24 8 | screen.columns = 80 9 | 10 | screen.rulerChar = 144 11 | screen.rulerTabChar = 145 12 | screen.vertChar = 149 13 | screen.horizChar = 154 14 | screen.lineNumbersChar = 149 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = RETURN 25 | keyname.escape = ESC 26 | 27 | key.up = ^_ 28 | key.down = ^^ 29 | key.left = ^A 30 | key.right = ^F 31 | key.begin = ^V 32 | key.end = ^E 33 | key.top = ^P 34 | key.bottom = ^S 35 | key.pgUp = ^Q 36 | key.pgDown = ^Z 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^G 41 | key.delLeft = ^? 42 | key.cut = ^U 43 | key.copy = ^R 44 | key.paste = ^W 45 | key.delete = ^D 46 | key.clearClip = ^T 47 | key.find = ^K 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_SPEC.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # SPECTRUM +3 & CP/M PLUS 4 | # ======================================== 5 | te.confName = "Spectrum +3 & CP/M 3" 6 | 7 | screen.rows = 23 8 | screen.columns = 51 9 | 10 | screen.rulerChar = 144 11 | screen.rulerTabChar = 145 12 | screen.vertChar = 149 13 | screen.horizChar = 154 14 | screen.lineNumbersChar = 149 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = ENTER 25 | keyname.escape = BREAK 26 | 27 | key.up = ^_ 28 | key.down = ^^ 29 | key.left = ^A 30 | key.right = ^F 31 | key.begin = ^V 32 | key.end = ^\ 33 | key.top = ^P 34 | key.bottom = ^S 35 | key.pgUp = ^Q 36 | key.pgDown = ^Z 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^G 41 | key.delLeft = ^? 42 | key.cut = ^U 43 | key.copy = ^R 44 | key.paste = ^W 45 | key.delete = ^D 46 | key.clearClip = ^T 47 | key.find = ^K 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_TAK.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # TAKEDA TOSHIYA'S CP/M EMULATOR 4 | # ======================================== 5 | te.confName = "Takeda Toshiya's CP/M emulator" 6 | 7 | screen.rows = 25 8 | screen.columns = 80 9 | 10 | screen.rulerChar = . 11 | screen.rulerTabChar = ! 12 | screen.vertChar = | 13 | screen.horizChar = - 14 | screen.lineNumbersChar = | 15 | 16 | editor.maxLines = 512 17 | editor.tabSize = 4 18 | editor.lineNumbers = true 19 | editor.c_language = true 20 | editor.autoIndent = true 21 | editor.autoList = true 22 | editor.listBullets = "-*>" 23 | 24 | keyname.newLine = ENTER 25 | keyname.escape = ESC 26 | 27 | key.up = ^E 28 | key.down = ^X 29 | key.left = ^S 30 | key.right = ^D 31 | key.begin = ^V 32 | key.end = ^A 33 | key.top = ^P 34 | key.bottom = ^F 35 | key.pgUp = ^R 36 | key.pgDown = ^C 37 | key.indent = ^I 38 | key.newLine = ^M 39 | key.escape = ^[ 40 | key.delRight = ^? 41 | key.delLeft = ^H 42 | key.cut = ^U 43 | key.copy = ^O 44 | key.paste = ^W 45 | key.delete = ^G 46 | key.clearClip = ^T 47 | key.find = ^K 48 | key.findNext = ^L 49 | key.goLine = ^J 50 | #key.wordLeft = "" 51 | #key.wordRight = "" 52 | key.blockStart = ^BS 53 | key.blockEnd = ^BE 54 | key.blockUnset = ^BU 55 | key.macro = ^Y 56 |  -------------------------------------------------------------------------------- /TE_APPLE.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # Default TE configuration for: 3 | # APPLE II 4 | # & SOFTCARD 5 | # & SOROC IQ 120 / 140 CRT 6 | # & WORDSTAR KEYS 7 | # ======================================== 8 | te.confName = "Apple II & Soroc & WordStar kb." 9 | 10 | screen.rows = 24 11 | screen.columns = 80 12 | 13 | screen.rulerChar = . 14 | screen.rulerTabChar = ! 15 | screen.vertChar = | 16 | screen.horizChar = - 17 | screen.lineNumbersChar = | 18 | 19 | editor.maxLines = 512 20 | editor.tabSize = 4 21 | editor.lineNumbers = true 22 | editor.c_language = true 23 | editor.autoIndent = true 24 | editor.autoList = true 25 | editor.listBullets = "-*>" 26 | 27 | keyname.newLine = RETURN 28 | keyname.escape = ESC 29 | 30 | key.up = ^E 31 | key.down = ^X 32 | key.left = ^S 33 | key.right = ^D 34 | key.begin = ^QS 35 | key.end = ^QD 36 | key.top = ^QR 37 | key.bottom = ^QC 38 | key.pgUp = ^R 39 | key.pgDown = ^C 40 | key.indent = ^I 41 | key.newLine = ^M 42 | key.escape = ^[ 43 | key.delRight = ^G 44 | key.delLeft = ^H 45 | key.cut = ^Y 46 | key.copy = ^O 47 | key.paste = ^W 48 | key.delete = ^KY 49 | key.clearClip = ^T 50 | key.find = ^QF 51 | key.findNext = ^L 52 | key.goLine = ^J 53 | key.wordLeft = ^A 54 | key.wordRight = ^F 55 | key.blockStart = ^KB 56 | key.blockEnd = ^KK 57 | key.blockUnset = ^KU 58 | key.macro = ^QM 59 |  -------------------------------------------------------------------------------- /te_misc.c: -------------------------------------------------------------------------------- 1 | /* te_misc.c 2 | 3 | Miscelaneous tools and functions. 4 | 5 | Operations with text lines. 6 | 7 | Copyright (c) 2015-2019 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 13 Jan 2019 : Added AllocMem(). 26 | 19 Jan 2019 : Added FreeArray(). 27 | 30 Jan 2019 : Added MatchStr(). 28 | */ 29 | 30 | /* Allocate memory 31 | --------------- 32 | Shows error message on failure. Returns same values as malloc(), 33 | */ 34 | AllocMem(bytes) 35 | unsigned int bytes; 36 | { 37 | char *p; 38 | 39 | if(!(p = malloc(bytes))) { 40 | ErrLineMem(); 41 | } 42 | 43 | return p; 44 | } 45 | 46 | /* Free array 47 | ---------- 48 | Deallocate array memory. 49 | */ 50 | FreeArray(arr, count, flag) 51 | int *arr, count, flag; 52 | { 53 | int i; 54 | 55 | for(i = 0; i < count; ++i) { 56 | if(arr[i]) { 57 | free(arr[i]); 58 | 59 | arr[i] = NULL; 60 | } 61 | } 62 | 63 | if(flag) { 64 | free(arr); 65 | } 66 | 67 | return NULL; 68 | } 69 | 70 | #if OPT_MACRO 71 | 72 | /* Test if two strings are equal 73 | ----------------------------- 74 | */ 75 | MatchStr(s1, s2) 76 | char *s1, *s2; 77 | { 78 | return !strcmp(s1, s2); 79 | } 80 | 81 | #endif 82 | 83 |  -------------------------------------------------------------------------------- /te_error.c: -------------------------------------------------------------------------------- 1 | /* te_error.c 2 | 3 | Text editor. 4 | 5 | Errors. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 30 Jan 2018 : Extracted from te.c. 26 | 25 Sep 2021 : Restore system message and cursor position when editing in ErrLine(). 27 | */ 28 | 29 | /* Print error message and wait for a key press 30 | -------------------------------------------- 31 | */ 32 | ErrLine(s) 33 | char *s; 34 | { 35 | SysLineCont(s); 36 | 37 | /* Restore system message and cursor position when editing */ 38 | if(editln) 39 | { 40 | SysLineEdit(); 41 | 42 | sysln = 0; 43 | 44 | CrtLocate(BOX_ROW + box_shr, box_shc + cf_num); 45 | } 46 | } 47 | 48 | /* No memory error 49 | --------------- 50 | */ 51 | ErrLineMem() 52 | { 53 | ErrLine("Not enough memory"); 54 | } 55 | 56 | /* Line too long error 57 | ------------------- 58 | */ 59 | ErrLineLong() 60 | { 61 | ErrLine("Line too long"); 62 | } 63 | 64 | /* Can't open file error 65 | --------------------- 66 | */ 67 | ErrLineOpen() 68 | { 69 | ErrLine("Can't open"); 70 | } 71 | 72 | /* Too many lines error 73 | -------------------- 74 | */ 75 | ErrLineTooMany() 76 | { 77 | ErrLine("Too many lines"); 78 | } 79 | 80 |  -------------------------------------------------------------------------------- /TE.CF: -------------------------------------------------------------------------------- 1 | # ======================================== 2 | # TE configuration file 3 | # ---------------------------------------- 4 | # IMPORTANT! This file is for TECF, the TE 5 | # configuration tool. 6 | # ======================================== 7 | 8 | # Configuration name 9 | #te.confName = "My own configuration" 10 | 11 | # Screen height: 8..255 or auto for CP/M 3 12 | #screen.rows = 25 13 | 14 | # Screen width: 64..255 or auto for CP/M 3 15 | #screen.columns = 80 16 | 17 | # Character for normal position in ruler 18 | #screen.rulerChar = "." 19 | 20 | # Character for tab stop position in ruler 21 | #screen.rulerTabChar = "!" 22 | 23 | # Character for vertical draws -- ie: help columns 24 | #screen.vertChar = "|" 25 | 26 | # Character for horizontal draws -- ie: status line 27 | #screen.horizChar = "-" 28 | 29 | # Character between line numbers and text 30 | screen.lineNumbersChar = " " 31 | 32 | # How many lines can edit: 256..4096 -- each 33 | # empty line occupies 2 bytes of RAM 34 | editor.maxLines = 512 35 | 36 | # How many columns (spaces) are a TAB: 1..16 37 | editor.tabSize = 4 38 | 39 | # Show line numbers: true / false 40 | editor.lineNumbers = true 41 | 42 | # C language type completion: [], {}, (), "", '', /**/ 43 | editor.c_language = true 44 | 45 | # Automatically indent a new line as the previous one 46 | editor.autoIndent = true 47 | 48 | # Automatically start a list when the first non blank 49 | # character in a line is one of "listBullets" -- max. 50 | # 7 characters in long 51 | editor.autoList = true 52 | editor.listBullets = "-*>" 53 | 54 | # Some keynames used in the UI 55 | #keyname.newLine = "ENTER" 56 | #keyname.escape = "ESC" 57 | 58 | # Key bindings, legal definitions are: 59 | # ^A -> Ctrl-A -> one control char. 60 | # ^A^X -> Ctrl-A, Ctrl-X -> two control chars. 61 | # ^AX -> Ctrl-A, X -> one control char., one char. 62 | # 63 | # Legal control characters are: 64 | # ^A..^Z ^[ ^\ ^] ^^ ^_ -> 1..31 65 | # ^? -> 127 66 | #key.up = "" 67 | #key.down = "" 68 | #key.left = "" 69 | #key.right = "" 70 | #key.begin = "" 71 | #key.end = "" 72 | #key.top = "" 73 | #key.bottom = "" 74 | #key.pgUp = "" 75 | #key.pgDown = "" 76 | #key.indent = "" 77 | #key.newLine = "" 78 | #key.escape = "" 79 | #key.delRight = "" 80 | #key.delLeft = "" 81 | #key.cut = "" 82 | #key.copy = "" 83 | #key.paste = "" 84 | #key.delete = "" 85 | #key.clearClip = "" 86 | #key.find = "" 87 | #key.findNext = "" 88 | #key.goLine = "" 89 | #key.wordLeft = "" 90 | #key.wordRight = "" 91 | #key.blockStart = "" 92 | #key.blockEnd = "" 93 | #key.blockUnset = "" 94 | #key.macro = "" 95 |  -------------------------------------------------------------------------------- /te_keys.h: -------------------------------------------------------------------------------- 1 | /* te.h 2 | 3 | Text editor. 4 | 5 | Definitions. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 05 Apr 2021 : Moved from te.h. 26 | 11 May 2021 : Remove default key names. 27 | 28 | Notes: 29 | 30 | This file is shared with TECF, the TE configuration tool. 31 | */ 32 | 33 | /* Key function codes 34 | ------------------ 35 | */ 36 | #define K_UP 1000 37 | #define K_DOWN 1001 38 | #define K_LEFT 1002 39 | #define K_RIGHT 1003 40 | #define K_BEGIN 1004 41 | #define K_END 1005 42 | #define K_TOP 1006 43 | #define K_BOTTOM 1007 44 | #define K_PGUP 1008 45 | #define K_PGDOWN 1009 46 | #define K_TAB 1010 47 | #define K_CR 1011 48 | #define K_ESC 1012 49 | #define K_RDEL 1013 50 | #define K_LDEL 1014 51 | #define K_CUT 1015 52 | #define K_COPY 1016 53 | #define K_PASTE 1017 54 | #define K_DELETE 1018 55 | #define K_CLRCLP 1019 56 | #define K_FIND 1020 57 | #define K_NEXT 1021 58 | #define K_GOTO 1022 59 | #define K_LWORD 1023 60 | #define K_RWORD 1024 61 | #define K_BLK_START 1025 62 | #define K_BLK_END 1026 63 | #define K_BLK_UNSET 1027 64 | #define K_MACRO 1028 65 | 66 | #define KEYS_MAX 29 /* Max. # of key bindings */ 67 | 68 | /* Control characters 69 | ------------------ 70 | */ 71 | #define CTL_A 1 72 | #define CTL_B 2 73 | #define CTL_C 3 74 | #define CTL_D 4 75 | #define CTL_E 5 76 | #define CTL_F 6 77 | #define CTL_G 7 78 | #define CTL_H 8 79 | #define CTL_I 9 80 | #define CTL_J 10 81 | #define CTL_K 11 82 | #define CTL_L 12 83 | #define CTL_M 13 84 | #define CTL_N 14 85 | #define CTL_O 15 86 | #define CTL_P 16 87 | #define CTL_Q 17 88 | #define CTL_R 18 89 | #define CTL_S 19 90 | #define CTL_T 20 91 | #define CTL_U 21 92 | #define CTL_V 22 93 | #define CTL_W 23 94 | #define CTL_X 24 95 | #define CTL_Y 25 96 | #define CTL_Z 26 97 | 98 | #define ZERO 0 99 | #define ESC 27 100 | #define DEL 127 101 | 102 |  -------------------------------------------------------------------------------- /te_keys.c: -------------------------------------------------------------------------------- 1 | /* te_keys.c 2 | 3 | Text editor. 4 | 5 | Key bindings. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 22 Jan 2019 : Start. 26 | 23 Jan 2019 : Added GetKeyWhat(). 27 | 29 Jan 2019 : Added K_CLRCLP. 28 | 26 Dec 2019 : Now K_INTRO is K_CR. Add GetKeyName(). 29 | 04 Apr 2021 : Remove customized key names. Use key bindings from configuration. 30 | 11 May 2021 : Update keys purposes. 31 | 10 Jul 2021 : Remove SetKey(). 32 | */ 33 | 34 | /* Return key name 35 | --------------- 36 | */ 37 | GetKeyName(key) 38 | int key; 39 | { 40 | switch(key) 41 | { 42 | case K_CR: return cf_cr_name; 43 | case K_ESC: return cf_esc_name; 44 | } 45 | 46 | return "?"; 47 | } 48 | 49 | /* Return key purpose 50 | ------------------ 51 | */ 52 | GetKeyWhat(key) 53 | int key; 54 | { 55 | /* Max. length of 8 chars., see MenuHelp() */ 56 | 57 | switch(key) 58 | { 59 | case K_UP: return "Up"; 60 | case K_DOWN: return "Down"; 61 | case K_LEFT: return "Left"; 62 | case K_RIGHT: return "Right"; 63 | case K_BEGIN: return "Begin"; 64 | case K_END: return "End"; 65 | case K_TOP: return "Top"; 66 | case K_BOTTOM: return "Bottom"; 67 | case K_PGUP: return "PgUp"; 68 | case K_PGDOWN: return "PgDown"; 69 | case K_TAB: return "Indent"; 70 | case K_CR: return "NewLine"; 71 | case K_ESC: return "Escape"; 72 | case K_RDEL: return "DelRight"; 73 | case K_LDEL: return "DelLeft"; 74 | case K_CUT: return "Cut"; 75 | case K_COPY: return "Copy"; 76 | case K_PASTE: return "Paste"; 77 | case K_DELETE: return "Delete"; 78 | case K_CLRCLP: return "ClearClip"; 79 | #if OPT_FIND 80 | case K_FIND: return "Find"; 81 | case K_NEXT: return "FindNext"; 82 | #endif 83 | #if OPT_GOTO 84 | case K_GOTO: return "GoLine"; 85 | #endif 86 | #if OPT_LWORD 87 | case K_LWORD: return "WordLeft"; 88 | #endif 89 | #if OPT_RWORD 90 | case K_RWORD: return "WordRight"; 91 | #endif 92 | #if OPT_BLOCK 93 | case K_BLK_START: return "BlockStart"; 94 | case K_BLK_END: return "BlockEnd"; 95 | case K_BLK_UNSET: return "BlockUnset"; 96 | #endif 97 | #if OPT_MACRO 98 | case K_MACRO: return "Macro"; 99 | #endif 100 | } 101 | 102 | return "?"; 103 | } 104 | 105 | /* Return key from keyboard, according to key bindings 106 | --------------------------------------------------- 107 | */ 108 | GetKey() 109 | { 110 | int c, x, i, k; 111 | 112 | c = CrtIn(); 113 | 114 | if(c > 31 && c != 127) { 115 | return c; 116 | } 117 | 118 | for(i = 0; i < KEYS_MAX; ++i) { 119 | if(cf_keys[i]) { 120 | if(c == cf_keys[i]) { 121 | if(cf_keys_ex[i]) { 122 | x = toupper(CrtIn()); 123 | 124 | /* TODO: try to optimize the following */ 125 | 126 | for(k = i; k < KEYS_MAX; ++k) { 127 | if(c == cf_keys[k]) { 128 | if(x == cf_keys_ex[k]) { 129 | return k + 1000; 130 | } 131 | } 132 | } 133 | break; 134 | } 135 | else { 136 | return i + 1000; 137 | } 138 | } 139 | } 140 | } 141 | 142 | return '?'; 143 | } 144 | 145 |  -------------------------------------------------------------------------------- /te_c128.c: -------------------------------------------------------------------------------- 1 | /* te_c128.c 2 | 3 | Text editor -- version for the Commodore 128. 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_c128 [filename] 24 | 25 | Compilation: 26 | 27 | cc te_c128 28 | ccopt te_c128 29 | zsm te_c128 30 | hextocom te_c128 31 | 32 | Changes: 33 | 34 | 11 Nov 2021 : 1st version. 35 | 36 | Notes: 37 | 38 | The C128 under CP/M Plus has an ADM-31 / 3A emulation 39 | and a 25x80 CRT minus 1 line for system messages. 40 | */ 41 | 42 | /* Default configuration values 43 | ---------------------------- 44 | */ 45 | #define CRT_DEF_ROWS 24 46 | #define CRT_DEF_COLS 80 47 | 48 | /* Options 49 | ------- 50 | Set to 1 to add the following functionalities, else 0. 51 | */ 52 | #define OPT_LWORD 0 /* Go to word on the left */ 53 | #define OPT_RWORD 0 /* Go to word on the right */ 54 | #define OPT_FIND 1 /* Find string */ 55 | #define OPT_GOTO 1 /* Go to line # */ 56 | #define OPT_BLOCK 1 /* Block selection */ 57 | #define OPT_MACRO 1 /* Enable macros */ 58 | 59 | /* Include main code 60 | ----------------- 61 | */ 62 | #include "te.c" 63 | 64 | /* Setup CRT: Used when the editor starts 65 | -------------------------------------- 66 | void CrtSetup(void) 67 | */ 68 | CrtSetup() 69 | { 70 | CrtSetupEx(); 71 | } 72 | 73 | #asm 74 | CrtSetupEx: 75 | ld hl,(1) 76 | inc hl 77 | inc hl 78 | inc hl 79 | ld de,BiosConst 80 | ld bc,9 81 | ldir 82 | ret 83 | 84 | BiosConst: jp 0 85 | BiosConin: jp 0 86 | BiosConout: jp 0 87 | #endasm 88 | 89 | /* Reset CRT: Used when the editor exits 90 | ------------------------------------- 91 | void CrtReset(void) 92 | */ 93 | CrtReset() 94 | { 95 | } 96 | 97 | /* Output character to the CRT 98 | --------------------------- 99 | All program output is done with this function. 100 | 101 | On '\n' outputs '\n' + '\r'. 102 | 103 | void CrtOut(int ch) 104 | */ 105 | #asm 106 | CrtOut: 107 | ld c,l 108 | ld a,l 109 | cp 10 110 | jp nz,BiosConout 111 | call BiosConout 112 | ld c,13 113 | jp BiosConout 114 | #endasm 115 | 116 | /* Input character from the keyboard 117 | --------------------------------- 118 | All program input is done with this function. 119 | 120 | int CrtIn(void) 121 | */ 122 | #asm 123 | CrtIn: 124 | call BiosConin 125 | ld h,0 126 | ld l,a 127 | ret 128 | #endasm 129 | 130 | /* Clear screen and send cursor to 0,0 131 | ----------------------------------- 132 | void CrtClear(void) 133 | */ 134 | CrtClear() 135 | { 136 | CrtOut(26); 137 | } 138 | 139 | /* Locate the cursor (HOME is 0,0) 140 | ------------------------------- 141 | void CrtLocate(int row, int col) 142 | */ 143 | CrtLocate(row, col) 144 | int row, col; 145 | { 146 | CrtOut(27); CrtOut('='); CrtOut(row + 32); CrtOut(col + 32); 147 | } 148 | 149 | /* Erase line and cursor to row,0 150 | ------------------------------ 151 | void CrtClearLine(int row) 152 | */ 153 | CrtClearLine(row) 154 | int row; 155 | { 156 | CrtLocate(row, 0); CrtClearEol(); 157 | } 158 | 159 | /* Erase from the cursor to the end of the line 160 | -------------------------------------------- 161 | */ 162 | CrtClearEol() 163 | { 164 | CrtOut(27); CrtOut('T'); 165 | } 166 | 167 | /* Turn on / off reverse video 168 | --------------------------- 169 | */ 170 | CrtReverse(on) 171 | int on; 172 | { 173 | CrtOut(27); CrtOut('G'); CrtOut(on ? '4' : '0'); 174 | } 175 | 176 |  -------------------------------------------------------------------------------- /te_sam.c: -------------------------------------------------------------------------------- 1 | /* te_sam.c 2 | 3 | Text editor -- version for the SAM Coupe. 4 | 5 | Copyright (c) 2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_sam [filename] 24 | 25 | Compilation: 26 | 27 | cc te_sam 28 | ccopt te_sam 29 | zsm te_sam 30 | hextocom te_sam 31 | 32 | Changes: 33 | 34 | 14 Nov 2021 : 1st version derived from the Amstrad PCW one. 35 | 36 | Notes: 37 | 38 | The SAM Coupe runs Pro-Dos (a CP/M 2.2 clone) with a VT52-like emulation, 39 | and a 24x80 CRT. 40 | */ 41 | 42 | /* Default configuration values 43 | ---------------------------- 44 | */ 45 | #define CRT_DEF_ROWS 24 46 | #define CRT_DEF_COLS 80 47 | 48 | /* Options 49 | ------- 50 | Set to 1 to add the following functionalities, else 0. 51 | */ 52 | #define OPT_LWORD 0 /* Go to word on the left */ 53 | #define OPT_RWORD 0 /* Go to word on the right */ 54 | #define OPT_FIND 1 /* Find string */ 55 | #define OPT_GOTO 1 /* Go to line # */ 56 | #define OPT_BLOCK 1 /* Block selection */ 57 | #define OPT_MACRO 1 /* Enable macros */ 58 | 59 | /* Include main code 60 | ----------------- 61 | */ 62 | #include "te.c" 63 | 64 | /* Setup CRT: Used when the editor starts 65 | -------------------------------------- 66 | void CrtSetup(void) 67 | */ 68 | CrtSetup() 69 | { 70 | CrtSetupEx(); 71 | } 72 | 73 | #asm 74 | CrtSetupEx: 75 | ld hl,(1) 76 | inc hl 77 | inc hl 78 | inc hl 79 | ld de,BiosConst 80 | ld bc,9 81 | ldir 82 | ret 83 | 84 | BiosConst: jp 0 85 | BiosConin: jp 0 86 | BiosConout: jp 0 87 | #endasm 88 | 89 | /* Reset CRT: Used when the editor exits 90 | ------------------------------------- 91 | void CrtReset(void) 92 | */ 93 | CrtReset() 94 | { 95 | } 96 | 97 | /* Output character to the CRT 98 | --------------------------- 99 | All program output is done with this function. 100 | 101 | On '\n' outputs '\n' + '\r'. 102 | 103 | void CrtOut(int ch) 104 | */ 105 | #asm 106 | CrtOut: 107 | ld c,l 108 | ld a,l 109 | cp 10 110 | jp nz,BiosConout 111 | call BiosConout 112 | ld c,13 113 | jp BiosConout 114 | #endasm 115 | 116 | /* Input character from the keyboard 117 | --------------------------------- 118 | All program input is done with this function. 119 | 120 | int CrtIn(void) 121 | */ 122 | #asm 123 | CrtIn: 124 | call BiosConin 125 | ld h,0 126 | ld l,a 127 | ret 128 | #endasm 129 | 130 | /* Clear screen and send cursor to 0,0 131 | ----------------------------------- 132 | void CrtClear(void) 133 | */ 134 | CrtClear() 135 | { 136 | CrtOut(27); CrtOut('H'); /* Cursor to 0,0 */ 137 | CrtOut(27); CrtOut('E'); /* Clear CRT */ 138 | } 139 | 140 | /* Locate the cursor (HOME is 0,0) 141 | ------------------------------- 142 | void CrtLocate(int row, int col) 143 | */ 144 | CrtLocate(row, col) 145 | int row, col; 146 | { 147 | CrtOut(27); CrtOut('Y'); CrtOut(row + 32); CrtOut(col + 32); 148 | } 149 | 150 | /* Erase line and cursor to row,0 151 | ------------------------------ 152 | void CrtClearLine(int row) 153 | */ 154 | CrtClearLine(row) 155 | int row; 156 | { 157 | CrtLocate(row, 0); CrtClearEol(); 158 | } 159 | 160 | /* Erase from the cursor to the end of the line 161 | -------------------------------------------- 162 | */ 163 | CrtClearEol() 164 | { 165 | CrtOut(27); CrtOut('K'); 166 | } 167 | 168 | /* Turn on / off reverse video 169 | --------------------------- 170 | */ 171 | CrtReverse(on) 172 | int on; 173 | { 174 | CrtOut(27); CrtOut(on ? 'p' : 'q'); 175 | } 176 | 177 |  -------------------------------------------------------------------------------- /te_apple.c: -------------------------------------------------------------------------------- 1 | /* te_apple.c 2 | 3 | Text editor -- version for the Apple II with SoftCard and 4 | a SOROC IQ 120 / 140 CRT. 5 | 6 | Copyright (c) 2021 Miguel Garcia / FloppySoftware 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the 10 | Free Software Foundation; either version 2, or (at your option) any 11 | later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not, write to the Free Software 20 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 | 22 | Usage: 23 | 24 | te_apple [filename] 25 | 26 | Compilation: 27 | 28 | cc te_apple 29 | ccopt te_apple 30 | zsm te_apple 31 | hextocom te_apple 32 | 33 | Changes: 34 | 35 | 14 Oct 2021 : 1st version. 36 | 37 | Notes: 38 | 39 | The Apple II with SoftCard runs CP/M v2.2. The SOROC IQ 120 / 140 is 40 | a 24x80 CRT with specific screen escape sequences. 41 | */ 42 | 43 | /* Default configuration values 44 | ---------------------------- 45 | */ 46 | #define CRT_DEF_ROWS 24 47 | #define CRT_DEF_COLS 80 48 | 49 | /* Options 50 | ------- 51 | Set to 1 to add the following functionalities, else 0. 52 | */ 53 | #define OPT_LWORD 0 /* Go to word on the left */ 54 | #define OPT_RWORD 0 /* Go to word on the right */ 55 | #define OPT_FIND 1 /* Find string */ 56 | #define OPT_GOTO 1 /* Go to line # */ 57 | #define OPT_BLOCK 1 /* Block selection */ 58 | #define OPT_MACRO 1 /* Enable macros */ 59 | 60 | /* Include main code 61 | ----------------- 62 | */ 63 | #include "te.c" 64 | 65 | /* Setup CRT: Used when the editor starts 66 | -------------------------------------- 67 | void CrtSetup(void) 68 | */ 69 | CrtSetup() 70 | { 71 | CrtSetupEx(); 72 | } 73 | 74 | #asm 75 | CrtSetupEx: 76 | ld hl,(1) 77 | inc hl 78 | inc hl 79 | inc hl 80 | ld de,BiosConst 81 | ld bc,9 82 | ldir 83 | ret 84 | 85 | BiosConst: jp 0 86 | BiosConin: jp 0 87 | BiosConout: jp 0 88 | #endasm 89 | 90 | /* Reset CRT: Used when the editor exits 91 | ------------------------------------- 92 | void CrtReset(void) 93 | */ 94 | CrtReset() 95 | { 96 | } 97 | 98 | /* Output character to the CRT 99 | --------------------------- 100 | All program output is done with this function. 101 | 102 | On '\n' outputs '\n' + '\r'. 103 | 104 | void CrtOut(int ch) 105 | */ 106 | #asm 107 | CrtOut: 108 | ld c,l 109 | ld a,l 110 | cp 10 111 | jp nz,BiosConout 112 | call BiosConout 113 | ld c,13 114 | jp BiosConout 115 | #endasm 116 | 117 | /* Input character from the keyboard 118 | --------------------------------- 119 | All program input is done with this function. 120 | 121 | Translate WordStar key sequences to TE key codes. 122 | 123 | int CrtIn(void) 124 | */ 125 | CrtIn() 126 | { 127 | int ch; 128 | 129 | switch(ch = CrtInEx()) { 130 | case DEL : /* DEL == CTL_H */ 131 | return CTL_H; 132 | case CTL_N : /* ^N == ^M */ 133 | return CTL_M; 134 | } 135 | 136 | return ch; 137 | } 138 | 139 | #asm 140 | CrtInEx: 141 | call BiosConin 142 | ld h,0 143 | ld l,a 144 | ret 145 | #endasm 146 | 147 | /* Clear screen and send cursor to 0,0 148 | ----------------------------------- 149 | void CrtClear(void) 150 | */ 151 | CrtClear() 152 | { 153 | CrtOut(30); /* Cursor to 0,0 */ 154 | CrtOut(27); CrtOut('*'); /* Clear CRT */ 155 | } 156 | 157 | /* Locate the cursor (HOME is 0,0) 158 | ------------------------------- 159 | void CrtLocate(int row, int col) 160 | */ 161 | CrtLocate(row, col) 162 | int row, col; 163 | { 164 | CrtOut(27); CrtOut('='); CrtOut(row + 32); CrtOut(col + 32); 165 | } 166 | 167 | /* Erase line and cursor to row,0 168 | ------------------------------ 169 | void CrtClearLine(int row) 170 | */ 171 | CrtClearLine(row) 172 | int row; 173 | { 174 | CrtLocate(row, 0); CrtClearEol(); 175 | } 176 | 177 | /* Erase from the cursor to the end of the line 178 | -------------------------------------------- 179 | */ 180 | CrtClearEol() 181 | { 182 | CrtOut(27); CrtOut('T'); 183 | } 184 | 185 | /* Turn on / off reverse video 186 | --------------------------- 187 | */ 188 | CrtReverse(on) 189 | int on; 190 | { 191 | CrtOut(27); CrtOut(on ? '(' : ')'); 192 | } 193 | 194 |  -------------------------------------------------------------------------------- /te_conf.c: -------------------------------------------------------------------------------- 1 | /* te_ui.c 2 | 3 | Text editor. 4 | 5 | Configuration variables. 6 | 7 | Copyright (c) 2020-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 22 Oct 2020 : Start. 26 | 22 Feb 2021 : Added screen rows and columns. 27 | 04 Apr 2021 : Added key bindings. 28 | 06 Apr 2021 : Added screen characters for various purposes. 29 | 11 May 2021 : Default values. 30 | 31 | Notes: 32 | 33 | This file is shared with TECF, the TE configuration tool. 34 | */ 35 | 36 | /* Configuration variables 37 | ----------------------- 38 | */ 39 | extern char cf_name[]; 40 | extern unsigned char cf_rows; 41 | extern unsigned char cf_cols; 42 | extern int cf_mx_lines; 43 | extern unsigned char cf_tab_cols; 44 | extern unsigned char cf_num; 45 | extern unsigned char cf_clang; 46 | extern unsigned char cf_indent; 47 | extern unsigned char cf_list; 48 | extern char cf_list_chr[]; 49 | extern char cf_cr_name[]; 50 | extern char cf_esc_name[]; 51 | extern unsigned char cf_keys[]; 52 | extern unsigned char cf_keys_ex[]; 53 | 54 | extern unsigned char cf_rul_chr; 55 | extern unsigned char cf_rul_tab; 56 | extern unsigned char cf_vert_chr; 57 | extern unsigned char cf_horz_chr; 58 | extern unsigned char cf_lnum_chr; 59 | 60 | extern unsigned int cf_start; 61 | extern unsigned char cf_version; 62 | extern int cf_bytes; 63 | 64 | #asm 65 | cf_start: 66 | defb 'TE_CONF', 0 ; 8 bytes > Identifier + ZERO for the configuration block in memory and COM file. 67 | 68 | cf_version: defb 2 ; 1 byte > Configuration version >= 0. It's not the TE version. 69 | 70 | cf_name: defb 0,0,0,0,0,0,0,0 ; 32 bytes > Configuration name + ZERO. 71 | defb 0,0,0,0,0,0,0,0 72 | defb 0,0,0,0,0,0,0,0 73 | defb 0,0,0,0,0,0,0,0 74 | 75 | cf_rows: defb 25 ; 1 byte > Screen rows or 0 for auto. 76 | cf_cols: defb 80 ; 1 byte > Screen columns or 0 for auto. 77 | 78 | cf_mx_lines: defw 512 ; 2 bytes > Max. number of lines in editor. 79 | ; Each line takes 2 bytes (1 word) of memory. 80 | 81 | cf_tab_cols: defb 4 ; 1 byte > How many spaces a tabulation inserts. 82 | 83 | cf_num: defb 4 ; 1 byte > Number of digits for line numbers (see cf_mx_lines) plus 1 84 | ; for the separator. Set to ZERO for no line numbers. 85 | 86 | cf_clang: defb 1 ; 1 byte > C language auto completion: [], {}, (), "", '', /**/. 87 | 88 | cf_indent: defb 1 ; 1 byte > Automatic indent according to the indent of previous line. 89 | 90 | cf_list: defb 1 ; 1 byte > Automatic list. 91 | cf_list_chr: defb '-*>',0,0,0,0,0 ; 8 byte > Legal characters for automatic lists + ZERO. 92 | 93 | cf_rul_chr: defb '.' ; 1 byte > Ruler: Character. 94 | cf_rul_tab: defb '!' ; 1 byte > Ruler: Tab stop character. 95 | 96 | cf_vert_chr: defb '|' ; 1 byte > Char. for vertical draws -- ie: for line numbers. 97 | cf_horz_chr: defb '-' ; 1 byte > Char. for horizontal draws -- ie: for status line. 98 | 99 | cf_lnum_chr: defb '|' ; 1 byte > Char. between line numbers and text. 100 | 101 | cf_cr_name: defb 0,0,0,0,0,0,0,0 ; 8 byte > CR key name 102 | cf_esc_name: defb 0,0,0,0,0,0,0,0 ; 8 byte > ESC key name 103 | 104 | cf_keys: defb 0,0,0,0,0,0,0,0 ; 29 bytes > 1st character in key binding. Must to be equal to KEYS_MAX. 105 | defb 0,0,0,0,0,0,0,0 106 | defb 0,0,0,0,0,0,0,0 107 | defb 0,0,0,0,0 108 | 109 | cf_keys_ex: defb 0,0,0,0,0,0,0,0 ; 29 bytes > 2nd character in key binding. Must to be equal to KEYS_MAX. 110 | defb 0,0,0,0,0,0,0,0 111 | defb 0,0,0,0,0,0,0,0 112 | defb 0,0,0,0,0 113 | 114 | cf_bytes: defw $ - cf_start + 2 ; 2 bytes > Block configuration size in bytes. 115 | 116 | #endasm 117 | 118 |  -------------------------------------------------------------------------------- /te_px8.c: -------------------------------------------------------------------------------- 1 | /* te_px8.c 2 | 3 | Text editor -- version for the Epson PX-8 "Geneva". 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_px8 [filename] 24 | 25 | Compilation: 26 | 27 | cc te_px8 28 | ccopt te_px8 29 | zsm te_px8 30 | hextocom te_px8 31 | 32 | Changes: 33 | 34 | 16 Feb 2020 : 1st version. 35 | 08 Mar 2020 : Alternative to reverse video. First public release. 36 | 14 Jan 2021 : Remove OPT_NUM. 37 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 38 | 04 Apr 2021 : Remove key bindings. 39 | 11 May 2021 : Remove CRT configuration values. 40 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 41 | 06 Jul 2021 : Optimize CrtOut(). 42 | 43 | Notes: 44 | 45 | The Epson PX-8 "Geneva" runs CP/M 2.2 with a physical LCD screen of 8x80. 46 | 47 | References: 48 | 49 | https://fjkraan.home.xs4all.nl/comp/px8 50 | */ 51 | 52 | /* Default configuration values 53 | ---------------------------- 54 | */ 55 | #define CRT_DEF_ROWS 8 56 | #define CRT_DEF_COLS 80 57 | 58 | /* Options 59 | ------- 60 | Set to 1 to add the following functionalities, else 0. 61 | */ 62 | #define OPT_LWORD 0 /* Go to word on the left */ 63 | #define OPT_RWORD 0 /* Go to word on the right */ 64 | #define OPT_FIND 1 /* Find string */ 65 | #define OPT_GOTO 1 /* Go to line # */ 66 | #define OPT_BLOCK 1 /* Block selection */ 67 | #define OPT_MACRO 1 /* Enable macros */ 68 | 69 | /* Definitions 70 | ----------- 71 | */ 72 | #define CRT_CAN_REV 0 /* Reverse video is not available */ 73 | #define CRT_LONG 0 /* CRT has few lines */ 74 | 75 | /* Include main code 76 | ----------------- 77 | */ 78 | #include "te.c" 79 | 80 | /* Setup CRT: Used when the editor starts 81 | -------------------------------------- 82 | void CrtSetup(void) 83 | */ 84 | CrtSetup() 85 | { 86 | CrtSetupEx(); 87 | } 88 | 89 | #asm 90 | CrtSetupEx: 91 | ld hl,(1) 92 | inc hl 93 | inc hl 94 | inc hl 95 | ld de,BiosConst 96 | ld bc,9 97 | ldir 98 | ret 99 | 100 | BiosConst: jp 0 101 | BiosConin: jp 0 102 | BiosConout: jp 0 103 | #endasm 104 | 105 | /* Reset CRT: Used when the editor exits 106 | ------------------------------------- 107 | void CrtReset(void) 108 | */ 109 | CrtReset() 110 | { 111 | // Display mode 0: 40 lines screen 0, 8 lines screen 2 112 | CrtOut(27); CrtOut(208); CrtOut(2); CrtOut(24); CrtOut(24); 113 | } 114 | 115 | /* Output character to the CRT 116 | --------------------------- 117 | All program output is done with this function. 118 | 119 | On '\n' outputs '\n' + '\r'. 120 | 121 | void CrtOut(int ch) 122 | */ 123 | #asm 124 | CrtOut: 125 | ld c,l 126 | ld a,l 127 | cp 10 128 | jp nz,BiosConout 129 | call BiosConout 130 | ld c,13 131 | jp BiosConout 132 | #endasm 133 | 134 | /* Input character from the keyboard 135 | --------------------------------- 136 | All program input is done with this function. 137 | 138 | int CrtIn(void) 139 | */ 140 | #asm 141 | CrtIn: 142 | call BiosConin 143 | ld h,0 144 | ld l,a 145 | ret 146 | #endasm 147 | 148 | /* Clear screen and send cursor to 0,0 149 | ----------------------------------- 150 | void CrtClear(void) 151 | */ 152 | CrtClear() 153 | { 154 | CrtOut(12); 155 | } 156 | 157 | /* Locate the cursor (HOME is 0,0) 158 | ------------------------------- 159 | void CrtLocate(int row, int col) 160 | */ 161 | CrtLocate(row, col) 162 | int row, col; 163 | { 164 | CrtOut(27); CrtOut('='); CrtOut(row + 32); CrtOut(col + 32); 165 | } 166 | 167 | /* Erase line and cursor to row,0 168 | ------------------------------ 169 | void CrtClearLine(int row) 170 | */ 171 | CrtClearLine(row) 172 | int row; 173 | { 174 | CrtLocate(row, 0); CrtClearEol(); 175 | } 176 | 177 | /* Erase from the cursor to the end of the line 178 | -------------------------------------------- 179 | */ 180 | CrtClearEol() 181 | { 182 | CrtOut(27); CrtOut('T'); 183 | } 184 | 185 | /* Turn on / off reverse video 186 | --------------------------- 187 | */ 188 | /* 189 | CrtReverse(on) 190 | int on; 191 | { 192 | CrtOut(27); CrtOut('['); CrtOut(on ? '7' : '0'); CrtOut('m'); 193 | } 194 | */ 195 | 196 |  -------------------------------------------------------------------------------- /te_kp.c: -------------------------------------------------------------------------------- 1 | /* te_kp.c 2 | 3 | Text editor -- version for the Kaypro II, 4, and 10 (and any other terminal 4 | emulating the ADM-3A) 5 | 6 | Adapted by Stephen S. Mitchell from a version for the Amstrad PCW 7 | written by Miguel Garcia / Floppy Software. 8 | 9 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 10 | 11 | This program is free software; you can redistribute it and/or modify it 12 | under the terms of the GNU General Public License as published by the 13 | Free Software Foundation; either version 2, or (at your option) any 14 | later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24 | 25 | Usage: 26 | 27 | te_kp [filename] 28 | 29 | Compilation: 30 | 31 | cc te_kp 32 | ccopt te_kp 33 | zsm te_kp 34 | hextocom te_kp 35 | 36 | Changes: 37 | 38 | Original code: July 4, 2015. 39 | 40 | 02 Jun 2016 : mgl : Minor changes. 41 | 25 Jan 2018 : mgl : Find & find next keys. 42 | 20 Feb 2018 : mgl : Macro & go to line # keys. 43 | 30 Dec 2018 : Refactorized i/o functions. 44 | 15 Jan 2019 : Added CrtReverse(). 45 | 18 Jan 2019 : Added K_DELETE. 46 | 23 Jan 2019 : Modified a lot for key bindings support. 47 | 29 Jan 2019 : Added K_CLRCLP. 48 | 24 Dec 2019 : Added OPT_NUM. 49 | 26 Dec 2019 : Now K_INTRO is K_CR. Remove CRT_ESC_KEY. 50 | 14 Jan 2021 : Remove OPT_NUM. 51 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 52 | 04 Apr 2021 : Remove key bindings. 53 | 11 May 2021 : Remove CRT configuration values. 54 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 55 | 06 Jul 2021 : Optimize CrtOut(). 56 | 57 | Notes: 58 | 59 | - 60 | */ 61 | 62 | /* Default configuration values 63 | ---------------------------- 64 | */ 65 | #define CRT_DEF_ROWS 24 66 | #define CRT_DEF_COLS 80 67 | 68 | /* Options 69 | ------- 70 | Set to 1 to add the following functionalities, else 0. 71 | */ 72 | #define OPT_LWORD 0 /* Go to word on the left */ 73 | #define OPT_RWORD 0 /* Go to word on the right */ 74 | #define OPT_FIND 1 /* Find string */ 75 | #define OPT_GOTO 1 /* Go to line # */ 76 | #define OPT_BLOCK 1 /* Block selection */ 77 | #define OPT_MACRO 1 /* Enable macros */ 78 | 79 | /* Include main code 80 | ----------------- 81 | */ 82 | #include "te.c" 83 | 84 | /* Setup CRT: Used when the editor starts 85 | -------------------------------------- 86 | void CrtSetup(void) 87 | */ 88 | CrtSetup() 89 | { 90 | CrtSetupEx(); 91 | } 92 | 93 | #asm 94 | CrtSetupEx: 95 | ld hl,(1) 96 | inc hl 97 | inc hl 98 | inc hl 99 | ld de,BiosConst 100 | ld bc,9 101 | ldir 102 | ret 103 | 104 | BiosConst: jp 0 105 | BiosConin: jp 0 106 | BiosConout: jp 0 107 | #endasm 108 | 109 | /* Reset CRT: Used when the editor exits 110 | ------------------------------------- 111 | void CrtReset(void) 112 | */ 113 | CrtReset() 114 | { 115 | } 116 | 117 | /* Output character to the CRT 118 | --------------------------- 119 | All program output is done with this function. 120 | 121 | On '\n' outputs '\n' + '\r'. 122 | 123 | void CrtOut(int ch) 124 | */ 125 | #asm 126 | CrtOut: 127 | ld c,l 128 | ld a,l 129 | cp 10 130 | jp nz,BiosConout 131 | call BiosConout 132 | ld c,13 133 | jp BiosConout 134 | #endasm 135 | 136 | /* Input character from the keyboard 137 | --------------------------------- 138 | All program input is done with this function. 139 | 140 | int CrtIn(void) 141 | */ 142 | #asm 143 | CrtIn: 144 | call BiosConin 145 | ld h,0 146 | ld l,a 147 | ret 148 | #endasm 149 | 150 | /* Clear screen and send cursor to 0,0 151 | ----------------------------------- 152 | void CrtClear(void) 153 | */ 154 | CrtClear() 155 | { 156 | CrtOut(26); 157 | } 158 | 159 | /* Locate the cursor (HOME is 0,0) 160 | ------------------------------- 161 | void CrtLocate(int row, int col) 162 | */ 163 | CrtLocate(row, col) 164 | int row, col; 165 | { 166 | CrtOut(27); CrtOut('='); CrtOut(row + 32); CrtOut(col + 32); 167 | } 168 | 169 | /* Erase line and cursor to row,0 170 | ------------------------------ 171 | void CrtClearLine(int row) 172 | */ 173 | CrtClearLine(row) 174 | int row; 175 | { 176 | CrtLocate(row, 0); CrtClearEol(); 177 | } 178 | 179 | /* Erase from the cursor to the end of the line 180 | -------------------------------------------- 181 | */ 182 | CrtClearEol() 183 | { 184 | CrtOut(24); 185 | } 186 | 187 | /* Turn on / off reverse video 188 | --------------------------- 189 | */ 190 | CrtReverse(on) 191 | int on; 192 | { 193 | CrtOut(27); CrtOut(on ? 'B' : 'C'); CrtOut('0'); 194 | } 195 | 196 |  -------------------------------------------------------------------------------- /te_pcw.c: -------------------------------------------------------------------------------- 1 | /* te_pcw.c 2 | 3 | Text editor -- version for the Amstrad PCW. 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_pcw [filename] 24 | 25 | Compilation: 26 | 27 | cc te_pcw 28 | ccopt te_pcw 29 | zsm te_pcw 30 | hextocom te_pcw 31 | 32 | Changes: 33 | 34 | 02 May 2015 : 1st version. 35 | 02 Jun 2016 : Minor changes. 36 | 25 Jan 2018 : Find & find next keys. 37 | 26 Jan 2018 : Key to execute macro from file. 38 | 04 Feb 2018 : Key to go to line #. 39 | 30 Dec 2018 : Refactorized i/o functions. 40 | 17 Jan 2019 : Added CrtReverse(). 41 | 18 Jan 2019 : Added K_DELETE. 42 | 23 Jan 2019 : Modified a lot for key bindings support. 43 | 29 Jan 2019 : Added K_CLRCLP. 44 | 24 Dec 2019 : Added OPT_NUM. 45 | 26 Dec 2019 : Now K_INTRO is K_CR. Remove CRT_ESC_KEY. 46 | 14 Jan 2021 : Remove OPT_NUM. 47 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 48 | 04 Apr 2021 : Remove key bindings. 49 | 11 May 2021 : Remove CRT configuration values. 50 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 51 | 06 Jul 2021 : Optimize CrtOut(). 52 | 53 | Notes: 54 | 55 | The Amstrad PCW runs CP/M Plus (v3.1) with a VT52-like emulation, 56 | and a 32x90 CRT minus 1 line for system messages (it can be enabled 57 | or disabled). 58 | */ 59 | 60 | /* Default configuration values 61 | ---------------------------- 62 | */ 63 | #define CRT_DEF_ROWS 31 64 | #define CRT_DEF_COLS 90 65 | 66 | /* Options 67 | ------- 68 | Set to 1 to add the following functionalities, else 0. 69 | */ 70 | #define OPT_LWORD 0 /* Go to word on the left */ 71 | #define OPT_RWORD 0 /* Go to word on the right */ 72 | #define OPT_FIND 1 /* Find string */ 73 | #define OPT_GOTO 1 /* Go to line # */ 74 | #define OPT_BLOCK 1 /* Block selection */ 75 | #define OPT_MACRO 1 /* Enable macros */ 76 | 77 | /* Include main code 78 | ----------------- 79 | */ 80 | #include "te.c" 81 | 82 | /* Setup CRT: Used when the editor starts 83 | -------------------------------------- 84 | void CrtSetup(void) 85 | */ 86 | CrtSetup() 87 | { 88 | CrtSetupEx(); 89 | } 90 | 91 | #asm 92 | CrtSetupEx: 93 | ld hl,(1) 94 | inc hl 95 | inc hl 96 | inc hl 97 | ld de,BiosConst 98 | ld bc,9 99 | ldir 100 | ret 101 | 102 | BiosConst: jp 0 103 | BiosConin: jp 0 104 | BiosConout: jp 0 105 | #endasm 106 | 107 | /* Reset CRT: Used when the editor exits 108 | ------------------------------------- 109 | void CrtReset(void) 110 | */ 111 | CrtReset() 112 | { 113 | } 114 | 115 | /* Output character to the CRT 116 | --------------------------- 117 | All program output is done with this function. 118 | 119 | On '\n' outputs '\n' + '\r'. 120 | 121 | void CrtOut(int ch) 122 | */ 123 | #asm 124 | CrtOut: 125 | ld c,l 126 | ld a,l 127 | cp 10 128 | jp nz,BiosConout 129 | call BiosConout 130 | ld c,13 131 | jp BiosConout 132 | #endasm 133 | 134 | /* Input character from the keyboard 135 | --------------------------------- 136 | All program input is done with this function. 137 | 138 | int CrtIn(void) 139 | */ 140 | #asm 141 | CrtIn: 142 | call BiosConin 143 | ld h,0 144 | ld l,a 145 | ret 146 | #endasm 147 | 148 | /* Clear screen and send cursor to 0,0 149 | ----------------------------------- 150 | void CrtClear(void) 151 | */ 152 | CrtClear() 153 | { 154 | CrtOut(27); CrtOut('H'); /* Cursor to 0,0 */ 155 | CrtOut(27); CrtOut('E'); /* Clear CRT */ 156 | } 157 | 158 | /* Locate the cursor (HOME is 0,0) 159 | ------------------------------- 160 | void CrtLocate(int row, int col) 161 | */ 162 | CrtLocate(row, col) 163 | int row, col; 164 | { 165 | CrtOut(27); CrtOut('Y'); CrtOut(row + 32); CrtOut(col + 32); 166 | } 167 | 168 | /* Erase line and cursor to row,0 169 | ------------------------------ 170 | void CrtClearLine(int row) 171 | */ 172 | CrtClearLine(row) 173 | int row; 174 | { 175 | CrtLocate(row, 0); CrtClearEol(); 176 | } 177 | 178 | /* Erase from the cursor to the end of the line 179 | -------------------------------------------- 180 | */ 181 | CrtClearEol() 182 | { 183 | CrtOut(27); CrtOut('K'); 184 | } 185 | 186 | /* Turn on / off reverse video 187 | --------------------------- 188 | */ 189 | CrtReverse(on) 190 | int on; 191 | { 192 | CrtOut(27); CrtOut(on ? 'p' : 'q'); 193 | } 194 | 195 |  -------------------------------------------------------------------------------- /te_mur.c: -------------------------------------------------------------------------------- 1 | /* te_mur.c 2 | 3 | Text editor -- version for the K. Murakami's CP/M emulator. 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_mur [filename] 24 | 25 | Compilation: 26 | 27 | cc te_mur 28 | ccopt te_mur 29 | zsm te_mur 30 | hextocom te_mur 31 | 32 | Changes: 33 | 34 | 03 May 2015 : 1st version. 35 | 02 Jun 2016 : Minor changes. 36 | 20 Feb 2018 : Find, find next, macro & go to line # keys. 37 | 30 Dec 2018 : Refactorized i/o functions. 38 | 15 Jan 2019 : Added CrtReverse(). 39 | 18 Jan 2019 : Added K_DELETE. 40 | 23 Jan 2019 : Modified a lot for key bindings support. 41 | 29 Jan 2019 : Added K_CLRCLP. 42 | 24 Dec 2019 : Added OPT_NUM. 43 | 26 Dec 2019 : Now K_INTRO is K_CR. Remove CRT_ESC_KEY. 44 | 14 Jan 2021 : Remove OPT_NUM. 45 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 46 | 04 Apr 2021 : Remove key bindings. 47 | 11 May 2021 : Remove CRT configuration values. 48 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 49 | 06 Jul 2021 : Optimize CrtOut(). 50 | 51 | Notes: 52 | 53 | For CPM.EXE / CP/M-80 program EXEcutor for Win32 v0.4 from K. Murakami. 54 | 55 | It emulates a 25x80 VT-100. 56 | 57 | It translates the PC scan codes to single characters. 58 | */ 59 | 60 | /* Default configuration values 61 | ---------------------------- 62 | */ 63 | #define CRT_DEF_ROWS 25 64 | #define CRT_DEF_COLS 80 65 | 66 | /* Options 67 | ------- 68 | Set to 1 to add the following functionalities, else 0. 69 | */ 70 | #define OPT_LWORD 0 /* Go to word on the left */ 71 | #define OPT_RWORD 0 /* Go to word on the right */ 72 | #define OPT_FIND 1 /* Find string */ 73 | #define OPT_GOTO 1 /* Go to line # */ 74 | #define OPT_BLOCK 1 /* Block selection */ 75 | #define OPT_MACRO 1 /* Enable macros */ 76 | 77 | /* Include main code 78 | ----------------- 79 | */ 80 | #include "te.c" 81 | 82 | /* Setup CRT: Used when the editor starts 83 | -------------------------------------- 84 | void CrtSetup(void) 85 | */ 86 | CrtSetup() 87 | { 88 | CrtSetupEx(); 89 | } 90 | 91 | #asm 92 | CrtSetupEx: 93 | ld hl,(1) 94 | inc hl 95 | inc hl 96 | inc hl 97 | ld de,BiosConst 98 | ld bc,9 99 | ldir 100 | ret 101 | 102 | BiosConst: jp 0 103 | BiosConin: jp 0 104 | BiosConout: jp 0 105 | #endasm 106 | 107 | /* Reset CRT: Used when the editor exits 108 | ------------------------------------- 109 | void CrtReset(void) 110 | */ 111 | CrtReset() 112 | { 113 | } 114 | 115 | /* Output character to the CRT 116 | --------------------------- 117 | All program output is done with this function. 118 | 119 | On '\n' outputs '\n' + '\r'. 120 | 121 | void CrtOut(int ch) 122 | */ 123 | #asm 124 | CrtOut: 125 | ld c,l 126 | ld a,l 127 | cp 10 128 | jp nz,BiosConout 129 | call BiosConout 130 | ld c,13 131 | jp BiosConout 132 | #endasm 133 | 134 | /* Input character from the keyboard 135 | --------------------------------- 136 | All program input is done with this function. 137 | 138 | int CrtIn(void) 139 | */ 140 | #asm 141 | CrtIn: 142 | call BiosConin 143 | ld h,0 144 | ld l,a 145 | ret 146 | #endasm 147 | 148 | /* Clear screen and send cursor to 0,0 149 | ----------------------------------- 150 | void CrtClear(void) 151 | */ 152 | CrtClear() 153 | { 154 | CrtOut(27); putstr("[1;1H"); /* Cursor to 0,0 */ 155 | CrtOut(27); putstr("[2J"); /* Clear CRT */ 156 | } 157 | 158 | /* Locate the cursor (HOME is 0,0) 159 | ------------------------------- 160 | void CrtLocate(int row, int col) 161 | */ 162 | CrtLocate(row, col) 163 | int row, col; 164 | { 165 | CrtOut(27); CrtOut('['); 166 | putint("%d", row + 1); CrtOut(';'); 167 | putint("%d", col + 1); CrtOut('H'); 168 | } 169 | 170 | /* Erase line and cursor to row,0 171 | ------------------------------ 172 | void CrtClearLine(int row) 173 | */ 174 | CrtClearLine(row) 175 | int row; 176 | { 177 | CrtLocate(row, 0); CrtClearEol(); 178 | } 179 | 180 | /* Erase from the cursor to the end of the line 181 | -------------------------------------------- 182 | */ 183 | CrtClearEol() 184 | { 185 | CrtOut(27); putstr("[K"); 186 | } 187 | 188 | /* Turn on / off reverse video 189 | --------------------------- 190 | */ 191 | CrtReverse(on) 192 | int on; 193 | { 194 | CrtOut(27); CrtOut('['); CrtOut(on ? '7' : '0'); CrtOut('m'); 195 | } 196 | 197 |  -------------------------------------------------------------------------------- /te_file.c: -------------------------------------------------------------------------------- 1 | /* te_file.c 2 | 3 | Text editor. 4 | 5 | File I/O. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 30 Jan 2018 : Extracted from te.c. 26 | 22 Feb 2018 : Check for buffer changes. 27 | 09 Jan 2018 : Optimize ReadFile(). 28 | 16 Jan 2019 : Added support for block selection. 29 | 19 Jan 2019 : Optimize WriteFile(). 30 | 04 Jan 2021 : Use configuration variables. 31 | */ 32 | 33 | /* Reset lines array 34 | ----------------- 35 | */ 36 | ResetLines() 37 | { 38 | int i; 39 | 40 | FreeArray(lp_arr, cf_mx_lines, 0); 41 | 42 | lp_cur = lp_now = lp_chg = box_shr = box_shc = 0; 43 | 44 | #if OPT_BLOCK 45 | 46 | blk_start = blk_end = -1; 47 | blk_count = 0; 48 | 49 | #endif 50 | 51 | } 52 | 53 | /* New file 54 | -------- 55 | */ 56 | NewFile() 57 | { 58 | /* Free current contents */ 59 | ResetLines(); 60 | 61 | /* No filename */ 62 | file_name[0] = '\0'; 63 | 64 | /* Build first line */ 65 | InsertLine(0, NULL); 66 | } 67 | 68 | /* Read text file 69 | -------------- 70 | Returns NZ on error. 71 | */ 72 | ReadFile(fn) 73 | char *fn; 74 | { 75 | FILE *fp; 76 | int ch, code, len, i, tabs, rare; 77 | unsigned char *p; 78 | 79 | /* Free current contents */ 80 | ResetLines(); 81 | 82 | /* Setup some things */ 83 | code = tabs = rare = 0; 84 | 85 | /* Open the file */ 86 | SysLine("Reading file... "); 87 | 88 | if(!(fp = fopen(fn, "r"))) 89 | { 90 | ErrLineOpen(); return -1; 91 | } 92 | 93 | /* Read the file */ 94 | for(i = 0; i < 32000; ++i) 95 | { 96 | if(!fgets(ln_dat, ln_max + 2, fp)) /* ln_max + CR + ZERO */ 97 | break; 98 | 99 | if(lp_now == cf_mx_lines) 100 | { 101 | ErrLineTooMany(); ++code; break; 102 | } 103 | 104 | len = strlen(ln_dat); 105 | 106 | if(ln_dat[len - 1] == '\n') 107 | ln_dat[--len] = 0; 108 | else if(len > ln_max) 109 | { 110 | ErrLineLong(); ++code; break; 111 | } 112 | 113 | if(!(lp_arr[lp_now] = AllocMem(len + 1))) 114 | { 115 | ++code; break; 116 | } 117 | 118 | p = strcpy(lp_arr[lp_now++], ln_dat); 119 | 120 | /* Change TABs to SPACEs, and check characters */ 121 | //while((ch = (*p & 0xFF))) 122 | while((ch = *p)) 123 | { 124 | if(ch < ' ') 125 | { 126 | if(ch == '\t') 127 | { 128 | *p = ' '; ++tabs; 129 | } 130 | else 131 | { 132 | *p = '?'; ++rare; 133 | } 134 | } 135 | 136 | ++p; 137 | } 138 | } 139 | 140 | /* Close the file */ 141 | fclose(fp); 142 | 143 | /* Check errors */ 144 | if(code) 145 | return -1; 146 | 147 | /* Check if empty file */ 148 | if(!lp_now) 149 | { 150 | /* Build first line */ 151 | InsertLine(0, NULL); 152 | } 153 | 154 | /* Check TABs */ 155 | if(tabs) 156 | ErrLine("Tabs changed to spaces"); 157 | 158 | /* Check rare chars. */ 159 | if(rare) 160 | ErrLine("Illegal characters changed to '?'"); 161 | 162 | /* Success */ 163 | return 0; 164 | } 165 | 166 | /* Backup the previous file with the same name 167 | ------------------------------------------- 168 | Return NZ on error. 169 | */ 170 | BackupFile(fn) 171 | char *fn; 172 | { 173 | FILE *fp; 174 | char *bkp; 175 | 176 | /* Check if file exists */ 177 | //if((fp = fopen(fn, "r")) != NULL) 178 | if((fp = fopen(fn, "r"))) 179 | { 180 | fclose(fp); 181 | 182 | bkp = "te.bkp"; 183 | 184 | /* Remove the previous backup file, if exists */ 185 | remove(bkp); 186 | 187 | /* Rename the old file as backup */ 188 | rename(fn, bkp); 189 | } 190 | } 191 | 192 | /* Write text file 193 | --------------- 194 | Returns NZ on error. 195 | */ 196 | WriteFile(fn) 197 | char *fn; 198 | { 199 | FILE *fp; 200 | int i; 201 | 202 | SysLine("Writing file... "); 203 | 204 | /* Backup old file */ 205 | BackupFile(fn); 206 | 207 | /* Open the file */ 208 | 209 | if(!(fp = fopen(fn, "w"))) 210 | { 211 | ErrLineOpen(); return -1; 212 | } 213 | 214 | /* Write the file */ 215 | for(i = 0; i < lp_now; ++i) 216 | { 217 | if(fputs(lp_arr[i], fp) == EOF || fputc('\n', fp) == EOF) { 218 | 219 | fclose(fp); remove(fn); 220 | 221 | ErrLine("Can't write"); 222 | 223 | return -1; 224 | } 225 | } 226 | 227 | /* Close the file */ 228 | if(fclose(fp) == EOF) 229 | { 230 | remove(fn); 231 | 232 | ErrLine("Can't close"); 233 | 234 | return -1; 235 | } 236 | 237 | /* Success */ 238 | return (lp_chg = 0); 239 | } 240 | 241 |  -------------------------------------------------------------------------------- /te_spec.c: -------------------------------------------------------------------------------- 1 | /* te_spec.c 2 | 3 | Text editor -- version for the Spectrum +3. 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_spec [filename] 24 | 25 | Compilation: 26 | 27 | cc te_spec 28 | ccopt te_spec 29 | zsm te_spec 30 | hextocom te_spec 31 | 32 | Changes: 33 | 34 | 06 May 2015 : 1st version. 35 | 31 Aug 2015 : Minor changes in comments. 36 | 02 Jun 2016 : Minor changes. 37 | 25 Jan 2018 : Find & find next keys. 38 | 20 Feb 2018 : Macro & go to line # keys. 39 | 30 Dec 2018 : Refactorized i/o functions. 40 | 17 Jan 2019 : Added CrtReverse(). 41 | 18 Jan 2019 : Added K_DELETE. 42 | 23 Jan 2019 : Modified a lot for key bindings support. 43 | 29 Jan 2019 : Added K_CLRCLP. 44 | 24 Dec 2019 : Added OPT_NUM. 45 | 26 Dec 2019 : Now K_INTRO is K_CR. Remove CRT_ESC_KEY. 46 | 14 Jan 2021 : Remove OPT_NUM. 47 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 48 | 04 Apr 2021 : Remove key bindings. 49 | 11 May 2021 : Remove CRT configuration values. 50 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 51 | 06 Jul 2021 : Optimize CrtOut(). 52 | 53 | Notes: 54 | 55 | The Spectrum +3 runs CP/M Plus (v3.1) with a VT52-like emulation, 56 | and a 24x51 CRT minus 1 line for system messages (it can be enabled 57 | or disabled). 58 | 59 | It supports 24x32 and 24x80 (in two pages) CRT modes also. 60 | */ 61 | 62 | /* Default configuration values 63 | ---------------------------- 64 | */ 65 | #define CRT_DEF_ROWS 23 66 | #define CRT_DEF_COLS 51 67 | 68 | /* Options 69 | ------- 70 | Set to 1 to add the following functionalities, else 0. 71 | */ 72 | #define OPT_LWORD 0 /* Go to word on the left */ 73 | #define OPT_RWORD 0 /* Go to word on the right */ 74 | #define OPT_FIND 1 /* Find string */ 75 | #define OPT_GOTO 1 /* Go to line # */ 76 | #define OPT_BLOCK 1 /* Block selection */ 77 | #define OPT_MACRO 1 /* Enable macros */ 78 | 79 | /* Include main code 80 | ----------------- 81 | */ 82 | #include "te.c" 83 | 84 | /* Setup CRT: Used when the editor starts 85 | -------------------------------------- 86 | void CrtSetup(void) 87 | */ 88 | CrtSetup() 89 | { 90 | CrtSetupEx(); 91 | 92 | CrtOut(27); CrtOut('3'); CrtOut(1); /* Set 24 x 51 mode */ 93 | } 94 | 95 | #asm 96 | CrtSetupEx: 97 | ld hl,(1) 98 | inc hl 99 | inc hl 100 | inc hl 101 | ld de,BiosConst 102 | ld bc,9 103 | ldir 104 | ret 105 | 106 | BiosConst: jp 0 107 | BiosConin: jp 0 108 | BiosConout: jp 0 109 | #endasm 110 | 111 | /* Reset CRT: Used when the editor exits 112 | ------------------------------------- 113 | void CrtReset(void) 114 | */ 115 | CrtReset() 116 | { 117 | } 118 | 119 | /* Output character to the CRT 120 | --------------------------- 121 | All program output is done with this function. 122 | 123 | On '\n' outputs '\n' + '\r'. 124 | 125 | void CrtOut(int ch) 126 | */ 127 | #asm 128 | CrtOut: 129 | ld c,l 130 | ld a,l 131 | cp 10 132 | jp nz,BiosConout 133 | call BiosConout 134 | ld c,13 135 | jp BiosConout 136 | #endasm 137 | 138 | /* Input character from the keyboard 139 | --------------------------------- 140 | All program input is done with this function. 141 | 142 | int CrtIn(void) 143 | */ 144 | #asm 145 | CrtIn: 146 | call BiosConin 147 | ld h,0 148 | ld l,a 149 | ret 150 | #endasm 151 | 152 | /* Clear screen and send cursor to 0,0 153 | ----------------------------------- 154 | void CrtClear(void) 155 | */ 156 | CrtClear() 157 | { 158 | CrtOut(27); CrtOut('H'); /* Cursor to 0,0 */ 159 | CrtOut(27); CrtOut('E'); /* Clear CRT */ 160 | } 161 | 162 | /* Locate the cursor (HOME is 0,0) 163 | ------------------------------- 164 | void CrtLocate(int row, int col) 165 | */ 166 | CrtLocate(row, col) 167 | int row, col; 168 | { 169 | CrtOut(27); CrtOut('Y'); CrtOut(row + 32); CrtOut(col + 32); 170 | } 171 | 172 | /* Erase line and cursor to row,0 173 | ------------------------------ 174 | void CrtClearLine(int row) 175 | */ 176 | CrtClearLine(row) 177 | int row; 178 | { 179 | CrtLocate(row, 0); CrtClearEol(); 180 | } 181 | 182 | /* Erase from the cursor to the end of the line 183 | -------------------------------------------- 184 | */ 185 | CrtClearEol() 186 | { 187 | CrtOut(27); CrtOut('K'); 188 | } 189 | 190 | /* Turn on / off reverse video 191 | --------------------------- 192 | */ 193 | CrtReverse(on) 194 | int on; 195 | { 196 | CrtOut(27); CrtOut(on ? 'p' : 'q'); 197 | } 198 | 199 |  -------------------------------------------------------------------------------- /te_cpc3.c: -------------------------------------------------------------------------------- 1 | /* te_cpc3.c 2 | 3 | Text editor -- version for the Amstrad CPC with CP/M 3. 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_cpc3 [filename] 24 | 25 | Compilation: 26 | 27 | cc te_cpc3 28 | ccopt te_cpc3 29 | zsm te_cpc3 30 | hextocom te_cpc3 31 | 32 | Changes: 33 | 34 | 05 May 2015 : 1st version. 35 | 20 Jun 2015 : Modified ESC key name. 36 | 02 Jun 2016 : Minor changes. 37 | 25 Jan 2018 : Find & find next keys. 38 | 20 Feb 2018 : Macro & go to line # keys. 39 | 30 Dec 2018 : Refactorized i/o functions. 40 | 17 Jan 2019 : Added CrtReverse(). 41 | 18 Jan 2019 : Added K_DELETE. 42 | 23 Jan 2019 : Modified a lot for key bindings support. 43 | 29 Jan 2019 : Added K_CLRCLP. 44 | 24 Dec 2019 : Added OPT_NUM. 45 | 26 Dec 2019 : Now K_INTRO is K_CR. Remove CRT_ESC_KEY. 46 | 14 Jan 2021 : Remove OPT_NUM. 47 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 48 | 04 Apr 2021 : Remove key bindings. 49 | 11 May 2021 : Remove CRT configuration values. 50 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 51 | 06 Jul 2021 : Optimize CrtOut(). 52 | 53 | Notes: 54 | 55 | The Amstrad CPC with CP/M Plus (v3.1) has a VT52-like emulation, 56 | and a 25x80 CRT minus 1 line for system messages (it can be enabled 57 | or disabled). 58 | 59 | In order to configure the keyboard for CP/M Plus, the following 60 | command must be executed before TE: 61 | 62 | SETKEYS KEYS.CCP 63 | */ 64 | 65 | /* Default configuration values 66 | ---------------------------- 67 | */ 68 | #define CRT_DEF_ROWS 24 69 | #define CRT_DEF_COLS 80 70 | 71 | /* Options 72 | ------- 73 | Set to 1 to add the following functionalities, else 0. 74 | */ 75 | #define OPT_LWORD 0 /* Go to word on the left */ 76 | #define OPT_RWORD 0 /* Go to word on the right */ 77 | #define OPT_FIND 1 /* Find string */ 78 | #define OPT_GOTO 1 /* Go to line # */ 79 | #define OPT_BLOCK 1 /* Block selection */ 80 | #define OPT_MACRO 1 /* Enable macros */ 81 | 82 | /* Include main code 83 | ----------------- 84 | */ 85 | #include "te.c" 86 | 87 | /* Setup CRT: Used when the editor starts 88 | -------------------------------------- 89 | void CrtSetup(void) 90 | */ 91 | CrtSetup() 92 | { 93 | CrtSetupEx(); 94 | 95 | CrtOut(27); CrtOut('x'); /* 24x80 mode on */ 96 | } 97 | 98 | #asm 99 | CrtSetupEx: 100 | ld hl,(1) 101 | inc hl 102 | inc hl 103 | inc hl 104 | ld de,BiosConst 105 | ld bc,9 106 | ldir 107 | ret 108 | 109 | BiosConst: jp 0 110 | BiosConin: jp 0 111 | BiosConout: jp 0 112 | #endasm 113 | 114 | /* Reset CRT: Used when the editor exits 115 | ------------------------------------- 116 | void CrtReset(void) 117 | */ 118 | CrtReset() 119 | { 120 | CrtOut(27); CrtOut('y'); /* 24x80 mode off */ 121 | } 122 | 123 | /* Output character to the CRT 124 | --------------------------- 125 | All program output is done with this function. 126 | 127 | On '\n' outputs '\n' + '\r'. 128 | 129 | void CrtOut(int ch) 130 | */ 131 | #asm 132 | CrtOut: 133 | ld c,l 134 | ld a,l 135 | cp 10 136 | jp nz,BiosConout 137 | call BiosConout 138 | ld c,13 139 | jp BiosConout 140 | #endasm 141 | 142 | /* Input character from the keyboard 143 | --------------------------------- 144 | All program input is done with this function. 145 | 146 | int CrtIn(void) 147 | */ 148 | #asm 149 | CrtIn: 150 | call BiosConin 151 | ld h,0 152 | ld l,a 153 | ret 154 | #endasm 155 | 156 | /* Clear screen and send cursor to 0,0 157 | ----------------------------------- 158 | void CrtClear(void) 159 | */ 160 | CrtClear() 161 | { 162 | CrtOut(27); CrtOut('H'); /* Cursor to 0,0 */ 163 | CrtOut(27); CrtOut('E'); /* Clear CRT */ 164 | } 165 | 166 | /* Locate the cursor (HOME is 0,0) 167 | ------------------------------- 168 | void CrtLocate(int row, int col) 169 | */ 170 | CrtLocate(row, col) 171 | int row, col; 172 | { 173 | CrtOut(27); CrtOut('Y'); CrtOut(row + 32); CrtOut(col + 32); 174 | } 175 | 176 | /* Erase line and cursor to row,0 177 | ------------------------------ 178 | void CrtClearLine(int row) 179 | */ 180 | CrtClearLine(row) 181 | int row; 182 | { 183 | CrtLocate(row, 0); CrtClearEol(); 184 | } 185 | 186 | /* Erase from the cursor to the end of the line 187 | -------------------------------------------- 188 | */ 189 | CrtClearEol() 190 | { 191 | CrtOut(27); CrtOut('K'); 192 | } 193 | 194 | /* Turn on / off reverse video 195 | --------------------------- 196 | */ 197 | CrtReverse(on) 198 | int on; 199 | { 200 | CrtOut(27); CrtOut(on ? 'p' : 'q'); 201 | } 202 | 203 |  -------------------------------------------------------------------------------- /te_lines.c: -------------------------------------------------------------------------------- 1 | /* te_lines.c 2 | 3 | Text editor. 4 | 5 | Operations with text lines. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 06 Jan 2019 : Extracted from te.c. 26 | 07 Jan 2019 : Added InsertLine(), AppendLine(), SplitLine(), DeleteLine(), JoinLines(). 27 | 08 Jan 2019 : Added SetLine(), ModifyLine(), ClearLine(). Modified InsertLine(). 28 | 04 Jan 2021 : Use configuration variables. 29 | */ 30 | 31 | /* Return line # of first line printed on the editor box 32 | ----------------------------------------------------- 33 | */ 34 | GetFirstLine() 35 | { 36 | return lp_cur - box_shr; 37 | } 38 | 39 | /* Return line # of last line printed on the editor box 40 | ---------------------------------------------------- 41 | */ 42 | GetLastLine() 43 | { 44 | int last; 45 | 46 | last = GetFirstLine() + box_rows - 1; 47 | 48 | return last >= lp_now - 1 ? lp_now - 1 : last; /* min(lp_now - 1, last) */ 49 | } 50 | 51 | /* Set text in line # 52 | ------------------ 53 | Set 'text' to NULL for empty lines. Return NZ on success, else Z. 54 | */ 55 | SetLine(line, text, insert) 56 | int line; char *text; int insert; 57 | { 58 | char *p; 59 | int i; 60 | 61 | if(insert && lp_now >= cf_mx_lines) { 62 | ErrLineTooMany(); 63 | 64 | return 0; 65 | } 66 | 67 | if(!text) { 68 | text = ""; 69 | } 70 | 71 | if((p = AllocMem(strlen(text) + 1))) { 72 | if(insert) { 73 | for(i = lp_now; i > line; --i) { 74 | lp_arr[i] = lp_arr[i - 1]; 75 | } 76 | 77 | ++lp_now; 78 | } 79 | else { 80 | if(lp_arr[line]) { 81 | free(lp_arr[line]); 82 | } 83 | } 84 | 85 | lp_arr[line] = strcpy(p, text); 86 | 87 | return 1; 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | /* Modify text in line # 94 | --------------------- 95 | Set 'text' to NULL for empty lines. Return NZ on success, else Z. 96 | */ 97 | 98 | ModifyLine(line, text) 99 | int line; char *text; 100 | { 101 | return SetLine(line, text, 0); 102 | } 103 | 104 | /* Clear text in line # 105 | -------------------- 106 | Return NZ on success, else Z. 107 | */ 108 | 109 | ClearLine(line) 110 | int line; 111 | { 112 | return ModifyLine(line, NULL); 113 | } 114 | 115 | /* Insert new line before line # 116 | ----------------------------- 117 | Set 'text' to NULL for empty lines. Return NZ on success, else Z. 118 | */ 119 | InsertLine(line, text) 120 | int line; char *text; 121 | { 122 | return SetLine(line, text, 1); 123 | } 124 | 125 | /* Append new line after line # 126 | ----------------------------- 127 | Set 'text' to NULL for empty lines. Return NZ on success, else Z. 128 | */ 129 | AppendLine(line, text) 130 | int line; char *text; 131 | { 132 | return InsertLine(line + 1, text); 133 | } 134 | 135 | /* Split line # into two lines 136 | --------------------------- 137 | Return NZ on success, else Z. 138 | */ 139 | SplitLine(line, pos) 140 | int line, pos; 141 | { 142 | char *p, *p2; 143 | 144 | if((p = AllocMem(pos + 1))) { 145 | if(AppendLine(line, lp_arr[line] + pos)) { 146 | 147 | /* We don't have strncpy() nor arrays of pointers yet, then... */ 148 | p2 = lp_arr[line]; 149 | 150 | p2[pos] = '\0'; 151 | 152 | strcpy(p, p2); 153 | 154 | free(p2); 155 | 156 | lp_arr[line] = p; 157 | 158 | return 1; 159 | } 160 | 161 | free(p); 162 | } 163 | 164 | return 0; 165 | } 166 | 167 | /* Delete line # 168 | ------------- 169 | Return NZ on success, else Z. 170 | */ 171 | DeleteLine(line) 172 | int line; 173 | { 174 | int i; 175 | 176 | free(lp_arr[line]); 177 | 178 | --lp_now; 179 | 180 | for(i = line; i < lp_now; ++i) { 181 | lp_arr[i] = lp_arr[i + 1]; 182 | } 183 | 184 | lp_arr[lp_now] = NULL; 185 | 186 | return 1; 187 | } 188 | 189 | /* Join two consecutive lines 190 | -------------------------- 191 | Return NZ on success, else Z. 192 | */ 193 | JoinLines(line) 194 | int line; 195 | { 196 | char *p, *p1, *p2; 197 | int s1, s2; 198 | 199 | p1 = lp_arr[line]; 200 | p2 = lp_arr[line + 1]; 201 | 202 | s1 = strlen(p1); 203 | s2 = strlen(p2); 204 | 205 | if(s1 + s2 <= ln_max) { 206 | if((p = AllocMem(s1 + s2 + 1))) { 207 | 208 | /* 209 | strcpy(p, p1); strcat(p, p2); 210 | 211 | lp_arr[line] = p; 212 | */ 213 | 214 | // 215 | lp_arr[line] = strcat(strcpy(p, p1), p2); 216 | // 217 | 218 | //lp_arr[line] = strcpy(strcpy(p, p1) + s1, p2); FIXME - What's wrong with this? 219 | 220 | free(p1); 221 | 222 | DeleteLine(line + 1); 223 | 224 | return 1; 225 | } 226 | } 227 | 228 | return 0; 229 | } 230 | 231 |  -------------------------------------------------------------------------------- /te_ws100.c: -------------------------------------------------------------------------------- 1 | /* te_ws100.c 2 | 3 | Text editor -- version for VT100 & WordStar keys, under CP/M. 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_ws100 [filename] 24 | 25 | Compilation: 26 | 27 | cc te_ws100 28 | ccopt te_ws100 29 | zsm te_ws100 30 | hextocom te_ws100 31 | 32 | Changes: 33 | 34 | 12 May 2015 : 1st version. 35 | 14 May 2015 : Completed adaptation for WS keys. 36 | 02 Jun 2016 : Minor changes. 37 | 11 Jun 2016 : Minor changes in help text. 38 | 24 Jan 2018 : Find & find next keys. 39 | 26 Jan 2018 : Key to execute macro from file. 40 | 04 Feb 2018 : Key to go to line #. 41 | 30 Dec 2018 : Refactorized i/o functions. 42 | 15 Jan 2019 : Added CrtReverse(). 43 | 18 Jan 2019 : Added K_DELETE. 44 | 23 Jan 2019 : Modified a lot for key bindings support. 45 | 29 Jan 2019 : Added K_CLRCLP. 46 | 24 Dec 2019 : Added OPT_NUM. 47 | 26 Dec 2019 : Now K_INTRO is K_CR. Remove CRT_ESC_KEY. 48 | 14 Jan 2021 : Remove OPT_NUM. 49 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 50 | 04 Apr 2021 : Remove key bindings. 51 | 11 May 2021 : Remove CRT configuration values. 52 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 53 | 06 Jul 2021 : Optimize CrtOut(). 54 | 55 | Notes: 56 | 57 | - 58 | */ 59 | 60 | /* Default configuration values 61 | ---------------------------- 62 | */ 63 | #define CRT_DEF_ROWS 25 64 | #define CRT_DEF_COLS 80 65 | 66 | /* Options 67 | ------- 68 | Set to 1 to add the following functionalities, else 0. 69 | */ 70 | #define OPT_LWORD 1 /* Go to word on the left */ 71 | #define OPT_RWORD 1 /* Go to word on the right */ 72 | #define OPT_FIND 1 /* Find string */ 73 | #define OPT_GOTO 1 /* Go to line # */ 74 | #define OPT_BLOCK 1 /* Block selection */ 75 | #define OPT_MACRO 1 /* Enable macros */ 76 | 77 | /* Include main code 78 | ----------------- 79 | */ 80 | #include "te.c" 81 | 82 | /* Setup CRT: Used when the editor starts 83 | -------------------------------------- 84 | void CrtSetup(void) 85 | */ 86 | CrtSetup() 87 | { 88 | CrtSetupEx(); 89 | } 90 | 91 | #asm 92 | CrtSetupEx: 93 | ld hl,(1) 94 | inc hl 95 | inc hl 96 | inc hl 97 | ld de,BiosConst 98 | ld bc,9 99 | ldir 100 | ret 101 | 102 | BiosConst: jp 0 103 | BiosConin: jp 0 104 | BiosConout: jp 0 105 | #endasm 106 | 107 | /* Reset CRT: Used when the editor exits 108 | ------------------------------------- 109 | void CrtReset(void) 110 | */ 111 | CrtReset() 112 | { 113 | } 114 | 115 | /* Output character to the CRT 116 | --------------------------- 117 | All program output is done with this function. 118 | 119 | On '\n' outputs '\n' + '\r'. 120 | 121 | void CrtOut(int ch) 122 | */ 123 | #asm 124 | CrtOut: 125 | ld c,l 126 | ld a,l 127 | cp 10 128 | jp nz,BiosConout 129 | call BiosConout 130 | ld c,13 131 | jp BiosConout 132 | #endasm 133 | 134 | /* Input character from the keyboard 135 | --------------------------------- 136 | All program input is done with this function. 137 | 138 | Translate WordStar key sequences to TE key codes. 139 | 140 | int CrtIn(void) 141 | */ 142 | CrtIn() 143 | { 144 | int ch; 145 | 146 | switch(ch = CrtInEx()) { 147 | case DEL : /* DEL == CTL_H */ 148 | return CTL_H; 149 | case CTL_N : /* ^N == ^M */ 150 | return CTL_M; 151 | } 152 | 153 | return ch; 154 | } 155 | 156 | #asm 157 | CrtInEx: 158 | call BiosConin 159 | ld h,0 160 | ld l,a 161 | ret 162 | #endasm 163 | 164 | /* Clear screen and send cursor to 0,0 165 | ----------------------------------- 166 | void CrtClear(void) 167 | */ 168 | CrtClear() 169 | { 170 | CrtOut(27); putstr("[1;1H"); /* Cursor to 0,0 */ 171 | CrtOut(27); putstr("[2J"); /* Clear CRT */ 172 | } 173 | 174 | /* Locate the cursor (HOME is 0,0) 175 | ------------------------------- 176 | void CrtLocate(int row, int col) 177 | */ 178 | CrtLocate(row, col) 179 | int row, col; 180 | { 181 | CrtOut(27); CrtOut('['); 182 | putint("%d", row + 1); CrtOut(';'); 183 | putint("%d", col + 1); CrtOut('H'); 184 | } 185 | 186 | /* Erase line and cursor to row,0 187 | ------------------------------ 188 | void CrtClearLine(int row) 189 | */ 190 | CrtClearLine(row) 191 | int row; 192 | { 193 | CrtLocate(row, 0); CrtClearEol(); 194 | } 195 | 196 | /* Erase from the cursor to the end of the line 197 | -------------------------------------------- 198 | */ 199 | CrtClearEol() 200 | { 201 | CrtOut(27); putstr("[K"); 202 | } 203 | 204 | /* Turn on / off reverse video 205 | --------------------------- 206 | */ 207 | CrtReverse(on) 208 | int on; 209 | { 210 | CrtOut(27); CrtOut('['); CrtOut(on ? '7' : '0'); CrtOut('m'); 211 | } 212 | 213 |  -------------------------------------------------------------------------------- /te_tak.c: -------------------------------------------------------------------------------- 1 | /* te_tak.c 2 | 3 | Text editor -- version for the Takeda Toshiya's CP/M emulator. 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_tak [filename] 24 | 25 | Compilation: 26 | 27 | cc te_tak 28 | ccopt te_tak 29 | zsm te_tak 30 | hextocom te_tak 31 | 32 | Changes: 33 | 34 | 06 May 2015 : 1st version. 35 | 02 Jun 2016 : Minor changes. 36 | 25 Jan 2018 : Find & find next keys. 37 | 26 Jan 2018 : Key to execute macro from file. 38 | 04 Feb 2018 : Key to go to line #. 39 | 30 Dec 2018 : Refactorized i/o functions. 40 | 15 Jan 2019 : Added CrtReverse(). 41 | 18 Jan 2019 : Added K_DELETE. 42 | 23 Jan 2019 : Modified a lot for key bindings support. 43 | 29 Jan 2019 : Added K_CLRCLP. 44 | 22 Dec 2019 : Modified K_BEGIN to CTL_V. 45 | 24 Dec 2019 : Added OPT_NUM. 46 | 26 Dec 2019 : Now K_INTRO is K_CR. Remove CRT_ESC_KEY. 47 | 14 Jan 2021 : Remove OPT_NUM. 48 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 49 | 04 Apr 2021 : Remove key bindings. 50 | 11 May 2021 : Remove CRT configuration values. 51 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 52 | 06 Jul 2021 : Optimize CrtOut(). 53 | 54 | Notes: 55 | 56 | For CPM.EXE / CP/M Player for Win32 console from Takeda Toshiya. 57 | 58 | It emulates a 25x80 VT-100. 59 | 60 | It needs to translate the IBM PC keyboard codes. 61 | */ 62 | 63 | /* Default configuration values 64 | ---------------------------- 65 | */ 66 | #define CRT_DEF_ROWS 25 67 | #define CRT_DEF_COLS 80 68 | 69 | /* Options 70 | ------- 71 | Set to 1 to add the following functionalities, else 0. 72 | */ 73 | #define OPT_LWORD 0 /* Go to word on the left */ 74 | #define OPT_RWORD 0 /* Go to word on the right */ 75 | #define OPT_FIND 1 /* Find string */ 76 | #define OPT_GOTO 1 /* Go to line # */ 77 | #define OPT_BLOCK 1 /* Block selection */ 78 | #define OPT_MACRO 1 /* Enable macros */ 79 | 80 | /* Include main code 81 | ----------------- 82 | */ 83 | #include "te.c" 84 | 85 | /* Setup CRT: Used when the editor starts 86 | -------------------------------------- 87 | void CrtSetup(void) 88 | */ 89 | CrtSetup() 90 | { 91 | CrtSetupEx(); 92 | } 93 | 94 | #asm 95 | CrtSetupEx: 96 | ld hl,(1) 97 | inc hl 98 | inc hl 99 | inc hl 100 | ld de,BiosConst 101 | ld bc,9 102 | ldir 103 | ret 104 | 105 | BiosConst: jp 0 106 | BiosConin: jp 0 107 | BiosConout: jp 0 108 | #endasm 109 | 110 | /* Reset CRT: Used when the editor exits 111 | ------------------------------------- 112 | void CrtReset(void) 113 | */ 114 | CrtReset() 115 | { 116 | } 117 | 118 | /* Output character to the CRT 119 | --------------------------- 120 | All program output is done with this function. 121 | 122 | On '\n' outputs '\n' + '\r'. 123 | 124 | void CrtOut(int ch) 125 | */ 126 | #asm 127 | CrtOut: 128 | ld c,l 129 | ld a,l 130 | cp 10 131 | jp nz,BiosConout 132 | call BiosConout 133 | ld c,13 134 | jp BiosConout 135 | #endasm 136 | 137 | /* Input character from the keyboard 138 | --------------------------------- 139 | All program input is done with this function. 140 | 141 | Translates the IBM PC key codes into single characters. 142 | 143 | int CrtIn(void) 144 | */ 145 | CrtIn() 146 | { 147 | int ch; 148 | 149 | ch = CrtInEx(); 150 | 151 | /* Translate key codes begining with 0 or 224 */ 152 | 153 | if(!ch || ch == 224) 154 | { 155 | ch = CrtInEx(); 156 | 157 | switch(ch) 158 | { 159 | case 72 : /* UP */ 160 | return 5; 161 | case 80 : /* DOWN */ 162 | return 24; 163 | case 75 : /* LEFT */ 164 | return 19; 165 | case 77 : /* RIGHT */ 166 | return 4; 167 | case 71 : /* HOME - INICIO */ 168 | return 22; 169 | case 79 : /* END */ 170 | return 1; 171 | case 73 : /* PGUP */ 172 | return 18; 173 | case 81 : /* PGDN */ 174 | return 3; 175 | case 83 : /* DELETE - SUPR */ 176 | return 127; 177 | case 119 : /* CTL HOME */ 178 | return 16; 179 | case 117 : /* CTL END */ 180 | return 6; 181 | case 59 : /* F1 */ 182 | return 21; 183 | case 60 : /* F2 */ 184 | return 15; 185 | case 61 : /* F3 */ 186 | return 23; 187 | case 62 : /* F4 */ 188 | return 7; 189 | default : 190 | return 0; 191 | } 192 | } 193 | 194 | return ch; 195 | } 196 | 197 | #asm 198 | CrtInEx: 199 | call BiosConin 200 | ld h,0 201 | ld l,a 202 | ret 203 | #endasm 204 | 205 | /* Clear screen and send cursor to 0,0 206 | ----------------------------------- 207 | void CrtClear(void) 208 | */ 209 | CrtClear() 210 | { 211 | CrtOut(27); putstr("[1;1H"); /* Cursor to 0,0 */ 212 | CrtOut(27); putstr("[2J"); /* Clear CRT */ 213 | } 214 | 215 | /* Locate the cursor (HOME is 0,0) 216 | ------------------------------- 217 | void CrtLocate(int row, int col) 218 | */ 219 | CrtLocate(row, col) 220 | int row, col; 221 | { 222 | CrtOut(27); CrtOut('['); 223 | putint("%d", row + 1); CrtOut(';'); 224 | putint("%d", col + 1); CrtOut('H'); 225 | } 226 | 227 | /* Erase line and cursor to row,0 228 | ------------------------------ 229 | void CrtClearLine(int row) 230 | */ 231 | CrtClearLine(row) 232 | int row; 233 | { 234 | CrtLocate(row, 0); CrtClearEol(); 235 | } 236 | 237 | /* Erase from the cursor to the end of the line 238 | -------------------------------------------- 239 | */ 240 | CrtClearEol() 241 | { 242 | CrtOut(27); putstr("[K"); 243 | } 244 | 245 | /* Turn on / off reverse video 246 | --------------------------- 247 | */ 248 | CrtReverse(on) 249 | int on; 250 | { 251 | CrtOut(27); CrtOut('['); CrtOut(on ? '7' : '0'); CrtOut('m'); 252 | } 253 | 254 |  -------------------------------------------------------------------------------- /te.h: -------------------------------------------------------------------------------- 1 | /* te.h 2 | 3 | Text editor. 4 | 5 | Definitions. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 04 May 2015 : 1st version. 26 | 12 May 2015 : v1.01 27 | 14 May 2015 : v1.02 28 | 15 May 2015 : v1.03 29 | 31 Aug 2015 : v1.04 30 | 02 Jun 2016 : v1.05 : CRT_FILE, CRT_ENGLISH, CRT_SPANISH, etc. are now out of this file. 31 | 10 Jun 2016 : v1.06 : Removed BOX_COL. Added PS_FNAME, PS_INF, PS_LIN_CUR, PS_LIN_NOW, 32 | PS_LIN_MAX, PS_COL_CUR, PS_COL_NOW, PS_COL_MAX. 33 | 14 Jun 2016 : v1.07 : Hack for SamaruX. 34 | 05 Jul 2017 : v1.08 35 | 24 Jan 2018 : v1.09 36 | 20 Feb 2018 : v1.10 : Defines for copyright and macros. 37 | 22 Feb 2018 : v1.11 38 | 26 Dec 2018 : v1.12 : Added MAC_SEP. 39 | 23 Jan 2019 : Added key function and character control codes. Added support for key binding. 40 | 27 Jan 2019 : Added support for macros. 41 | 29 Jan 2019 : Added K_CLRCLP. Show clipboard status on information line. 42 | 30 Jan 2019 : Removed support for SamaruX. 43 | 15 Feb 2019 : v1.13 44 | 24 Dec 2019 : Added MAX_DIGITS. 45 | 26 Dec 2019 : Now K_INTRO is K_CR. 46 | 27 Dec 2019 : v1.20 47 | 29 Feb 2020 : Adjust KEYS_MAX. 48 | 01 Mar 2020 : Added OPT_CLANG. Set default options. 49 | 02 Mar 2020 : Added OPT_INDENT. 50 | 04 Mar 2020 : v1.30 51 | 08 Mar 2020 : v1.40 : Added CRT_CAN_REV. 52 | 22 Dec 2020 : Added MAC_FTYPE. 53 | 31 Dec 2020 : Added OPT_LIST, LIST_CHRS, NUM_SEP. Added default values for layout characters. 54 | 05 Jan 2021 : Remove MAX_DIGITS. 55 | 14 Jan 2021 : Remove OPT_NUM, TAB_COLS. 56 | 18 Jan 2021 : v1.50 57 | 22 Feb 2021 : Remove CRT_COLS. 58 | 22 Feb 2021 : v1.60 59 | 04 Apr 2021 : Added K_CR_NAME, K_ESC_NAME. 60 | 05 Apr 2021 : Move key defs. to te_keys.h. 61 | 09 Jun 2021 : Remove RULER_TAB, RULER_CHR, SYS_LINE_SEP, NUM_SEP. 62 | 30 Jun 2021 : Add CRT_DEF_ROWS, CRT_DEF_COLS. 63 | 01 Jul 2021 : v1.70 64 | 05 Jul 2021 : Added OPT_Z80. 65 | 06 Jul 2021 : Added MAC_SYM_SIZ. Remove MAX_LINES. 66 | 25 Sep 2021 : v1.71 67 | 01 Nov 2021 : v1.72 68 | 20 Nov 2021 : v1.73 69 | 70 | Notes: 71 | 72 | Change TE_VERSION as required, before compilation. 73 | */ 74 | 75 | /* Version 76 | ------- 77 | */ 78 | #define VERSION "v1.73 / 20 Nov 2021 for CP/M" 79 | 80 | /* Copyright 81 | --------- 82 | */ 83 | #define COPYRIGHT "(c) 2015-2021 Miguel Garcia / FloppySoftware" 84 | 85 | /* Default options 86 | --------------- 87 | */ 88 | #ifndef CRT_DEF_ROWS 89 | #define CRT_DEF_ROWS 24 /* Default screen rows */ 90 | #endif 91 | 92 | #ifndef CRT_DEF_COLS 93 | #define CRT_DEF_COLS 80 /* Default screen columns */ 94 | #endif 95 | 96 | #ifndef OPT_Z80 97 | #define OPT_Z80 1 /* Write some things as Z80 assembler */ 98 | #endif 99 | 100 | #ifndef OPT_LWORD 101 | #define OPT_LWORD 1 /* Go to word on the left */ 102 | #endif 103 | 104 | #ifndef OPT_RWORD 105 | #define OPT_RWORD 1 /* Go to word on the right */ 106 | #endif 107 | 108 | #ifndef OPT_FIND 109 | #define OPT_FIND 1 /* Find string */ 110 | #endif 111 | 112 | #ifndef OPT_GOTO 113 | #define OPT_GOTO 1 /* Go to line # */ 114 | #endif 115 | 116 | #ifndef OPT_BLOCK 117 | #define OPT_BLOCK 1 /* Block selection */ 118 | #endif 119 | 120 | #ifndef OPT_MACRO 121 | #define OPT_MACRO 1 /* Enable macros */ 122 | #endif 123 | 124 | /* CRT defs. 125 | --------- 126 | */ 127 | #ifndef CRT_CAN_REV 128 | #define CRT_CAN_REV 1 129 | #endif 130 | 131 | #ifndef CRT_LONG 132 | #define CRT_LONG 1 133 | #endif 134 | 135 | /* Layout characters 136 | ----------------- 137 | */ 138 | #if CRT_CAN_REV 139 | #else 140 | #ifndef BLOCK_CHR 141 | #define BLOCK_CHR '*' /* Character to mark lines as selected, when CRT_CAN_REV == 0 */ 142 | #endif 143 | #endif 144 | 145 | /* More defs. 146 | ---------- 147 | */ 148 | #define FORCED_MAX 128 /* Keyboard forced entry buffer size (for paste, tabs, etc.) */ 149 | 150 | #define FIND_MAX 32 /* Find string buffer size */ 151 | 152 | #define PS_ROW 0 /* Information position */ 153 | #define PS_FNAME 4 /* Filename - position in row */ 154 | #define PS_TXT "--- | Lin:0000/0000/0000 Col:00/00 Len:00" /* Information layout */ 155 | #define PS_INF (cf_cols - 41) /* Information layout - position in row */ 156 | #define PS_CLP (cf_cols - 41) /* Clipboard status */ 157 | #define PS_LIN_CUR (cf_cols - 31) /* Current line # - position in row */ 158 | #define PS_LIN_NOW (cf_cols - 26) /* How many lines # - position in row */ 159 | #define PS_LIN_MAX (cf_cols - 21) /* Max. # of lines - position in row */ 160 | #define PS_COL_CUR (cf_cols - 12) /* Current column # - position in row */ 161 | #define PS_COL_NOW (cf_cols - 2) /* Line length - position in row */ 162 | #define PS_COL_MAX (cf_cols - 9) /* Max. line length - position in row */ 163 | 164 | #if CRT_LONG 165 | #define BOX_ROW 2 /* Editor box position */ 166 | #else 167 | #define BOX_ROW 1 168 | #endif 169 | 170 | #define getchr GetKey /* Get a character from the keyboard */ 171 | #define putchr CrtOut /* Print a character on screen */ 172 | 173 | #if OPT_MACRO 174 | 175 | /* Macros 176 | ------ 177 | */ 178 | #define MAC_START '{' /* Left delimiter for symbol names in macros */ 179 | #define MAC_END '}' /* Right delimiter for symbol names in macros */ 180 | #define MAC_SEP ':' /* Separator between symbol names and # of repeats */ 181 | #define MAC_ESCAPE '\\' /* For escaped characters in macros */ 182 | #define MAC_SYM_MAX 10 /* Max. length of macro symbol name in characters */ 183 | #define MAC_SYM_SIZ 11 /* MAC_SYM_MAX + '\0' */ 184 | #define MAC_FTYPE ".m" /* Default filetype for macro files */ 185 | 186 | #endif 187 | 188 |  -------------------------------------------------------------------------------- /te_ansi.c: -------------------------------------------------------------------------------- 1 | /* te_ansi.c 2 | 3 | Text editor -- version for the ANSI terminal. 4 | 5 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 2, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Usage: 22 | 23 | te_ansi [filename] 24 | 25 | Compilation: 26 | 27 | cc te_ansi 28 | ccopt te_ansi 29 | zsm te_ansi 30 | hextocom te_ansi 31 | 32 | Changes: 33 | 34 | 20 Oct 2020 : 1st version from source for the Takeda Toshiya's CP/M emulator. 35 | 14 Jan 2021 : Remove OPT_NUM. 36 | 22 Feb 2021 : Move CRT_ROWS, CRT_COLS to assembler. 37 | 04 Apr 2021 : Remove key bindings. 38 | 11 May 2021 : Remove CRT configuration values. 39 | 30 Jun 2021 : Added CRT_DEF_ROWS, CRT_DEF_COLS. 40 | 06 Jul 2021 : Optimize CrtOut(). 41 | 17 Jun 2023 : Add some delay in CrtInSt() to make real hardware happy. 42 | 18 Jun 2023 : Add input translations for PgUp and PgDn. Add alternate input translations for Begin and End (VT100). 43 | 44 | Notes: 45 | 46 | It emulates a 25x80 ANSI terminal. 47 | 48 | It needs to translate some keyboard codes. 49 | */ 50 | 51 | /* Default configuration values 52 | ---------------------------- 53 | */ 54 | #define CRT_DEF_ROWS 25 55 | #define CRT_DEF_COLS 80 56 | 57 | /* Options 58 | ------- 59 | Set to 1 to add the following functionalities, else 0. 60 | */ 61 | #define OPT_LWORD 0 /* Go to word on the left */ 62 | #define OPT_RWORD 0 /* Go to word on the right */ 63 | #define OPT_FIND 1 /* Find string */ 64 | #define OPT_GOTO 1 /* Go to line # */ 65 | #define OPT_BLOCK 1 /* Block selection */ 66 | #define OPT_MACRO 1 /* Enable macros */ 67 | 68 | /* Include main code 69 | ----------------- 70 | */ 71 | #include "te.c" 72 | 73 | /* Setup CRT: Used when the editor starts 74 | -------------------------------------- 75 | void CrtSetup(void) 76 | */ 77 | CrtSetup() 78 | { 79 | CrtSetupEx(); 80 | } 81 | 82 | #asm 83 | CrtSetupEx: 84 | ld hl,(1) 85 | inc hl 86 | inc hl 87 | inc hl 88 | ld de,BiosConst 89 | ld bc,9 90 | ldir 91 | ret 92 | 93 | BiosConst: jp 0 94 | BiosConin: jp 0 95 | BiosConout: jp 0 96 | #endasm 97 | 98 | /* Reset CRT: Used when the editor exits 99 | ------------------------------------- 100 | void CrtReset(void) 101 | */ 102 | CrtReset() 103 | { 104 | } 105 | 106 | /* Output character to the CRT 107 | --------------------------- 108 | All program output is done with this function. 109 | 110 | On '\n' outputs '\n' + '\r'. 111 | 112 | void CrtOut(int ch) 113 | */ 114 | #asm 115 | CrtOut: 116 | ld c,l 117 | ld a,l 118 | cp 10 119 | jp nz,BiosConout 120 | call BiosConout 121 | ld c,13 122 | jp BiosConout 123 | #endasm 124 | 125 | /* Input character from the keyboard 126 | --------------------------------- 127 | All program input is done with this function. 128 | 129 | Translates the ANSI key codes into single characters. 130 | 131 | int CrtIn(void) 132 | */ 133 | CrtIn() 134 | { 135 | int ch, ex; 136 | 137 | ch = CrtInEx(); 138 | 139 | /* Translate key codes begining with 0x1B (ESC): 140 | 141 | UP: ESC [ A --> ^E 142 | DOWN: ESC [ B --> ^X 143 | RIGHT: ESC [ C --> ^D 144 | LEFT: ESC [ D --> ^S 145 | HOME: ESC [ H --> ^V 146 | END: ESC [ F --> ^A 147 | PGUP: ESC [ 5 ~ --> ^R 148 | PGDN: ESC [ 6 ~ --> ^C 149 | HOME: ESC [ 7 ~ --> ^V (VT100) 150 | END: ESC [ 8 ~ --> ^A (VT100) 151 | */ 152 | 153 | if(ch == 0x1B) 154 | { 155 | if(CrtInSt()) 156 | { 157 | ch = 0; 158 | 159 | if(CrtInEx() == '[') 160 | { 161 | if(CrtInSt()) 162 | { 163 | switch((ex = CrtInEx())) 164 | { 165 | case 'A' : /* UP */ 166 | return CTL_E; 167 | case 'B' : /* DOWN */ 168 | return CTL_X; 169 | case 'C' : /* RIGHT */ 170 | return CTL_D; 171 | case 'D' : /* LEFT */ 172 | return CTL_S; 173 | case 'H' : /* HOME */ 174 | return CTL_V; 175 | case 'F' : /* END */ 176 | return CTL_A; 177 | case '5' : /* PGUP */ 178 | case '6' : /* PGDN */ 179 | case '7' : /* HOME */ 180 | case '8' : /* END */ 181 | if(CrtInSt()) 182 | { 183 | if(CrtInEx() == '~') { 184 | if(ex == '5') { 185 | return CTL_R; 186 | } 187 | else if(ex == '6') { 188 | return CTL_C; 189 | } 190 | else if(ex == '7') { 191 | return CTL_V; 192 | } 193 | else { 194 | return CTL_A; 195 | } 196 | } 197 | } 198 | break; 199 | } 200 | } 201 | } 202 | } 203 | } 204 | 205 | return ch; 206 | } 207 | 208 | #asm 209 | CrtInSt: 210 | ld hl,8200 211 | 212 | CrtInSt0: 213 | dec hl 214 | 215 | ld a,h 216 | or l 217 | 218 | jr nz,CrtInSt0 219 | 220 | call BiosConst 221 | ld h,0 222 | ld l,a 223 | ret 224 | 225 | CrtInEx: 226 | call BiosConin 227 | ld h,0 228 | ld l,a 229 | ret 230 | #endasm 231 | 232 | /* Clear screen and send cursor to 0,0 233 | ----------------------------------- 234 | void CrtClear(void) 235 | */ 236 | CrtClear() 237 | { 238 | CrtOut(27); putstr("[1;1H"); /* Cursor to 0,0 */ 239 | CrtOut(27); putstr("[2J"); /* Clear CRT */ 240 | } 241 | 242 | /* Locate the cursor (HOME is 0,0) 243 | ------------------------------- 244 | void CrtLocate(int row, int col) 245 | */ 246 | CrtLocate(row, col) 247 | int row, col; 248 | { 249 | CrtOut(27); CrtOut('['); 250 | putint("%d", row + 1); CrtOut(';'); 251 | putint("%d", col + 1); CrtOut('H'); 252 | } 253 | 254 | /* Erase line and cursor to row,0 255 | ------------------------------ 256 | void CrtClearLine(int row) 257 | */ 258 | CrtClearLine(row) 259 | int row; 260 | { 261 | CrtLocate(row, 0); CrtClearEol(); 262 | } 263 | 264 | /* Erase from the cursor to the end of the line 265 | -------------------------------------------- 266 | */ 267 | CrtClearEol() 268 | { 269 | CrtOut(27); putstr("[K"); 270 | } 271 | 272 | /* Turn on / off reverse video 273 | --------------------------- 274 | */ 275 | CrtReverse(on) 276 | int on; 277 | { 278 | CrtOut(27); CrtOut('['); CrtOut(on ? '7' : '0'); CrtOut('m'); 279 | } 280 | 281 |  -------------------------------------------------------------------------------- /te_macro.c: -------------------------------------------------------------------------------- 1 | /* te_macro.c 2 | 3 | Text editor. 4 | 5 | Macros. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 30 Jan 2018 : Extracted from te.c. 26 | 20 Feb 2018 : Disable code for macros from strings, for now. 27 | 26 Dec 2018 : Allow # of repeats in macros - ie {up:12}. Rename MacroGetCh() to MacroGet(). 28 | 29 Dec 2018 : Added MacroRunning(). 29 | 26 Dec 2019 : Now K_INTRO is K_CR. 30 | 01 Jul 2021 : Change macro symbol names to match key bindings names. 31 | 06 Jul 2021 : Optimize MacroGet() a bit. 32 | 25 Sep 2021 : Added MacroIsCmdChar(). Allow comments as {# comment}. Send '\0' from MacroStop(). 33 | 01 Nov 2021 : Modified MacroRunFile() to set raw mode and return success / error flag. 34 | Modified MacroGetRaw() and MacroGet() to support raw mode. 35 | Check in MacroGetRaw() for illegal characters. 36 | 18 Nov 2021 : Added {AutoIndent}, {AutoList}. 37 | 20 Nov 2021 : Added MatchSym(). 38 | */ 39 | 40 | /* Run a macro from file 41 | --------------------- 42 | Returns NZ on error. 43 | */ 44 | MacroRunFile(fname, raw) 45 | char *fname; 46 | int raw; 47 | { 48 | if(!(mac_fp = fopen(fname, "r"))) 49 | { 50 | ErrLineOpen(); 51 | 52 | return -1; 53 | } 54 | 55 | mac_raw = raw; 56 | 57 | /* Reset auto-indentation and auto-list */ 58 | mac_indent = cf_indent; 59 | mac_list = cf_list; 60 | 61 | cf_indent = cf_list = 0; 62 | 63 | return 0; 64 | } 65 | 66 | /* Run a macro from string 67 | ----------------------- 68 | */ 69 | /* 70 | MacroRunStr(s) 71 | char *s; 72 | { 73 | mac_str = s; 74 | } 75 | */ 76 | 77 | /* Tell if a macro is running 78 | -------------------------- 79 | */ 80 | MacroRunning() 81 | { 82 | return mac_fp != NULL /* || mac_str != NULL */; 83 | } 84 | 85 | /* Stop a macro 86 | ------------ 87 | */ 88 | MacroStop() 89 | { 90 | if(mac_fp) 91 | { 92 | fclose(mac_fp); 93 | } 94 | 95 | mac_fp = /*mac_str =*/ NULL; 96 | 97 | /* Restore auto-indentation and auto-list */ 98 | cf_indent = mac_indent; 99 | cf_list = mac_list; 100 | 101 | /* Flag end of input */ 102 | ForceCh('\0'); 103 | } 104 | 105 | /* Read raw character from macro input 106 | ----------------------------------- 107 | */ 108 | MacroGetRaw() 109 | { 110 | int ch; 111 | 112 | if(mac_fp) 113 | { 114 | if(mac_raw) 115 | { 116 | /* Raw mode - translate some control chars. */ 117 | switch(ch = fgetc(mac_fp)) 118 | { 119 | case '\n' : ch = K_CR; break; 120 | case '\t' : ch = ' '; break; 121 | } 122 | } 123 | else 124 | { 125 | /* Normal mode: ignore new-lines */ 126 | while((ch = fgetc(mac_fp)) == '\n') 127 | ; 128 | } 129 | 130 | if(ch != EOF) 131 | { 132 | /* Translate control chars. */ 133 | if(ch < 32 || ch == 127) 134 | { 135 | ch = '?'; 136 | } 137 | 138 | return ch; 139 | } 140 | 141 | MacroStop(); 142 | } 143 | /* 144 | else if(mac_str) 145 | { 146 | if(*mac_str) 147 | { 148 | return *mac_str++; 149 | } 150 | 151 | MacroStop(); 152 | } 153 | */ 154 | 155 | /* No character available */ 156 | return '\0'; 157 | } 158 | 159 | /* Check if a character is legal for symbol name 160 | --------------------------------------------- 161 | */ 162 | MacroIsCmdChar(ch) 163 | char ch; 164 | { 165 | return isalpha(ch) || ch == '#' || ch == '+' || ch == '-'; 166 | } 167 | 168 | /* Check if a string is a symbol 169 | ----------------------------- 170 | */ 171 | MatchSym(s) 172 | char *s; 173 | { 174 | return MatchStr(mac_sym, s); 175 | } 176 | 177 | /* Process a macro input unit 178 | -------------------------- 179 | */ 180 | MacroGet() 181 | { 182 | int i, n, ch; 183 | 184 | /* Continue if there is a character available */ 185 | if((ch = MacroGetRaw())) 186 | { 187 | /* Return character if raw mode */ 188 | if(mac_raw) 189 | { 190 | ForceCh(ch); 191 | 192 | return; 193 | } 194 | 195 | /* Return character if it's not the start of a symbol */ 196 | if(ch != MAC_START) 197 | { 198 | /* Check for escaped characters */ 199 | if(ch != MAC_ESCAPE) 200 | { 201 | ForceCh(ch); 202 | } 203 | else 204 | { 205 | if((ch = MacroGetRaw())) 206 | { 207 | ForceCh(ch); 208 | } 209 | else 210 | { 211 | /* Error: missing escaped character */ 212 | ErrLine("Bad escape sequence"); 213 | 214 | MacroStop(); 215 | } 216 | } 217 | 218 | return; 219 | } 220 | 221 | /* Get symbol name like {up} or {up:12} --> "up" */ 222 | for(i = 0; MacroIsCmdChar(ch = MacroGetRaw()) && i < MAC_SYM_MAX; ++i) 223 | { 224 | mac_sym[i] = tolower(ch); 225 | } 226 | 227 | if(i) 228 | { 229 | /* End of symbol name */ 230 | mac_sym[i] = '\0'; 231 | 232 | /* Get # of repeats if any - ie: {up:12} --> 12 */ 233 | if(ch == MAC_SEP) 234 | { 235 | n = 0; 236 | 237 | while(isdigit(ch = MacroGetRaw())) 238 | n = n * 10 + ch - '0'; 239 | 240 | if(n < 0 || n > FORCED_MAX) 241 | { 242 | n = -1; 243 | } 244 | } 245 | else 246 | { 247 | n = 1; 248 | } 249 | 250 | if(n >= 0) 251 | { 252 | /* Check for comments */ 253 | if(ch == ' ') 254 | { 255 | if((MatchSym("#"))) 256 | { 257 | while((ch = MacroGetRaw())) 258 | { 259 | if(ch == MAC_END) 260 | { 261 | ForceCh('\0'); 262 | 263 | return; 264 | } 265 | } 266 | } 267 | } 268 | 269 | /* Check for commands */ 270 | if(ch == MAC_END) 271 | { 272 | /* Do command action */ 273 | ch = 0; 274 | 275 | if (MatchSym("up")) ch = K_UP; 276 | else if(MatchSym("down")) ch = K_DOWN; 277 | else if(MatchSym("left")) ch = K_LEFT; 278 | else if(MatchSym("right")) ch = K_RIGHT; 279 | else if(MatchSym("begin")) ch = K_BEGIN; 280 | else if(MatchSym("end")) ch = K_END; 281 | else if(MatchSym("top")) ch = K_TOP; 282 | else if(MatchSym("bottom")) ch = K_BOTTOM; 283 | else if(MatchSym("newline")) ch = K_CR; 284 | else if(MatchSym("indent")) ch = K_TAB; 285 | else if(MatchSym("delright")) ch = K_RDEL; 286 | else if(MatchSym("delleft")) ch = K_LDEL; 287 | else if(MatchSym("cut")) ch = K_CUT; 288 | else if(MatchSym("copy")) ch = K_COPY; 289 | else if(MatchSym("paste")) ch = K_PASTE; 290 | else if(MatchSym("delete")) ch = K_DELETE; 291 | else if(MatchSym("clearclip")) ch = K_CLRCLP; 292 | 293 | #if OPT_BLOCK 294 | else if(MatchSym("blockstart")) ch = K_BLK_START; 295 | else if(MatchSym("blockend")) ch = K_BLK_END; 296 | #endif 297 | 298 | if(ch) 299 | { 300 | while(n--) 301 | { 302 | if(ForceCh(ch)) 303 | break; 304 | } 305 | 306 | return; 307 | } 308 | 309 | /* Special commands */ 310 | if(MatchSym("filename")) 311 | { 312 | while(n--) 313 | ForceStr(CurrentFile()); 314 | 315 | return; 316 | } 317 | else if(MatchSym("autoindent")) { 318 | cf_indent = (n ? 1 : 0); 319 | 320 | ForceCh('\0'); 321 | 322 | return; 323 | } 324 | else if(MatchSym("autolist")) { 325 | cf_list = (n ? 1 : 0); 326 | 327 | ForceCh('\0'); 328 | 329 | return; 330 | } 331 | } 332 | } 333 | } 334 | 335 | /* Error: symbol name not found, bad formed, too large, bad # of repeats */ 336 | ErrLine("Bad symbol"); 337 | 338 | MacroStop(); 339 | } 340 | } 341 | 342 |  -------------------------------------------------------------------------------- /tetx.c: -------------------------------------------------------------------------------- 1 | /* tetx.c 2 | 3 | TE text tool. 4 | 5 | Copyright (c) 2021 Miguel Garcia / FloppySoftware 6 | 7 | This program is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published by the 9 | Free Software Foundation; either version 3, or (at your option) any 10 | later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 | 21 | Author's contact: 22 | 23 | http://www.floppysoftware.es/ 24 | https://cpm-connections.blogspot.com 25 | floppysoftware@gmail.com 26 | 27 | To compile with MESCC under CP/M: 28 | 29 | cc tetx 30 | ccopt tetx 31 | zsm tetx 32 | hextocom tetx 33 | 34 | Usage: 35 | 36 | tetx 37 | 38 | Revisions: 39 | 40 | 03 Nov 2021 : Start. 41 | 04 Nov 2021 : v1.00. 42 | 20 Nov 2021 : Refactorized in order to read full lines. Add -S option. 43 | 20 Nov 2021 : v1.01. 44 | 25 Nov 2021 : Bugfix on error opening file. 45 | 25 Nov 2021 : v1.02. 46 | 47 | Notes: 48 | 49 | - 50 | */ 51 | 52 | /* MESCC libraries 53 | --------------- 54 | */ 55 | #define CC_STDIO /* Support for stdin, stdout, stderr */ 56 | #define CC_REDIR /* Support for command line redirection - needs CC_STDIO */ 57 | #define CC_FGETS /* Include fgets() */ 58 | 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | 67 | /* Project defs. 68 | ------------- 69 | */ 70 | #define APP_NAME "TETX" 71 | #define APP_VERSION "v1.02 / 25 Nov 2021" 72 | #define APP_COPYRGT "(c) 2021 Miguel Garcia / FloppySoftware" 73 | #define APP_INFO "TE text tool." 74 | #define APP_USAGE "tetx [-options...] [fname...] [> fname]" 75 | #define APP_OPT_E "-e Skip empty lines." 76 | #define APP_OPT_L "-l Convert to lowercase." 77 | #define APP_OPT_N "-n Print line numbers." 78 | #define APP_OPT_T "-t[N] Convert tab to spaces (default = 4)." 79 | #define APP_OPT_U "-u Convert to uppercase." 80 | #define APP_OPT_W "-wN Max. width of lines (32..255)." 81 | #define APP_OPT_S "-s Trim spaces on the right." 82 | #define APP_EX_1 "tetx -ne mydoc.txt" 83 | #define APP_EX_2 "tetx -t4u -n letter1.txt letter2.txt > letters.txt" 84 | 85 | #define TAB_SPACES 4 /* How many spaces are a tab by default */ 86 | #define TAB_MIN 1 /* Minimum number of spaces for a tab */ 87 | #define TAB_MAX 16 /* Maximum number of spaces for a tab */ 88 | 89 | #define WIDTH_MIN 32 /* Minimum width of lines */ 90 | #define WIDTH_MAX 255 /* Maximum width of lines */ 91 | 92 | #define BUF_SIZE 257 /* WIDTH_MAX + \n + \0 */ 93 | 94 | /* Options flags 95 | ------------- 96 | */ 97 | #define FLAG_E 1 /* Skip empty lines ? */ 98 | #define FLAG_L 2 /* Convert to lowercase */ 99 | #define FLAG_N 4 /* Print line numbers */ 100 | #define FLAG_T 8 /* Convert tab to spaces */ 101 | #define FLAG_U 16 /* Convert to uppercase */ 102 | #define FLAG_W 32 /* Max. width of lines */ 103 | #define FLAG_S 64 /* Trim spaces on the right */ 104 | 105 | /* Globals 106 | ------- 107 | */ 108 | int flags; 109 | int line; 110 | int tab_spaces; 111 | int width; 112 | int col; 113 | char buf[BUF_SIZE]; 114 | 115 | /* Program entry 116 | ------------- 117 | */ 118 | main(argc, argv) 119 | int argc; 120 | unsigned int argv[]; // char *argv[] - unsupported by MESCC (yet?) 121 | { 122 | int i, n; 123 | char *p; 124 | 125 | /* Show usage if there are no arguments */ 126 | if(argc == 1) { 127 | usage(); 128 | } 129 | 130 | /* Defaults */ 131 | flags = 0; 132 | line = 1; 133 | tab_spaces = TAB_SPACES; 134 | 135 | /* Check arguments */ 136 | for(i = 1; i < argc; ++i) { 137 | p = argv[i]; 138 | 139 | if(*p == '-') { 140 | while(*++p) { 141 | switch(*p) { 142 | case 'E' : flags |= FLAG_E; break; 143 | case 'L' : flags |= FLAG_L; break; 144 | case 'N' : flags |= FLAG_N; break; 145 | case 'T' : flags |= FLAG_T; 146 | n = 0; 147 | 148 | if(isdigit(*(p+1))) { 149 | do { 150 | n = n * 10 + (*(++p) - '0'); 151 | } while(isdigit(*(p+1))); 152 | 153 | if(n >= TAB_MIN && n <= TAB_MAX) { 154 | tab_spaces = n; 155 | } 156 | else { 157 | error("Illegal number of spaces"); 158 | } 159 | } 160 | 161 | break; 162 | case 'U' : flags |= FLAG_U; break; 163 | case 'W' : flags |= FLAG_W; 164 | n = 0; 165 | 166 | if(isdigit(*(p+1))) { 167 | do { 168 | n = n * 10 + (*(++p) - '0'); 169 | } while(isdigit(*(p+1))); 170 | 171 | if(n >= WIDTH_MIN && n <= WIDTH_MAX) { 172 | width = n; 173 | } 174 | else { 175 | error("Illegal width of lines"); 176 | } 177 | } 178 | 179 | break; 180 | case 'S' : flags |= FLAG_S; break; 181 | default : error("Unknown option"); 182 | } 183 | } 184 | } 185 | else { 186 | break; 187 | } 188 | } 189 | 190 | /* Process files */ 191 | if(i == argc) { 192 | tx_file("-"); 193 | } 194 | else { 195 | for(i = i; i < argc; ++i) { 196 | if(tx_file(argv[i])) 197 | return -1; 198 | } 199 | } 200 | 201 | /* Return success */ 202 | return 0; 203 | } 204 | 205 | /* Process file 206 | ------------ 207 | */ 208 | tx_file(fn) 209 | char *fn; 210 | { 211 | FILE *fp; 212 | int len; 213 | 214 | /* Open */ 215 | if(*fn == '-' && !fn[1]) { 216 | fp = stdin; 217 | } 218 | else if((fp = fopen(fn, "r")) == NULL) { 219 | error_fname("Can't open", fn); 220 | } 221 | 222 | /* Process lines */ 223 | for(;;) { 224 | if(!fgets(buf, BUF_SIZE, fp)) { 225 | break; 226 | } 227 | 228 | len = strlen(buf); 229 | 230 | if(buf[len - 1] == '\n') { 231 | buf[--len] = '\0'; 232 | } 233 | else if(len > WIDTH_MAX) 234 | { 235 | error("Line too long"); 236 | } 237 | 238 | tx_line(len); 239 | } 240 | 241 | /* Close */ 242 | if(fp != stdin) { 243 | fclose(fp); 244 | } 245 | 246 | /* Success */ 247 | return 0; 248 | } 249 | 250 | /* Process line 251 | ------------ 252 | */ 253 | tx_line(len) 254 | int len; 255 | { 256 | int i; 257 | 258 | /* Setup */ 259 | col = 0; 260 | 261 | /* Trim spaces on the right ? */ 262 | if(flags & FLAG_S) { 263 | while(len) { 264 | if(buf[len - 1] != ' ') { 265 | break; 266 | } 267 | 268 | buf[--len] = '\0'; 269 | } 270 | } 271 | 272 | /* Lowercase ? */ 273 | if(flags & FLAG_L) { 274 | for(i = 0; i < len; ++i) { 275 | buf[i] = tolower(buf[i]); 276 | } 277 | } 278 | 279 | /* Uppercase ? */ 280 | if(flags & FLAG_U) { 281 | for(i = 0; i < len; ++i) { 282 | buf[i] = toupper(buf[i]); 283 | } 284 | } 285 | 286 | /* Process characters */ 287 | for(i = 0; i < len; ++i) { 288 | tx_out(buf[i]); 289 | } 290 | 291 | tx_out('\n'); 292 | } 293 | 294 | /* Process character and output result 295 | ----------------------------------- 296 | */ 297 | tx_out(ch) 298 | int ch; 299 | { 300 | int k; 301 | 302 | /* New line ? */ 303 | if(ch == '\n') { 304 | 305 | /* Empty line ? */ 306 | if(col == 0) { 307 | 308 | /* Skip empty lines ? */ 309 | if(flags & FLAG_E) { 310 | return; 311 | } 312 | } 313 | } 314 | 315 | /* Start of line ? */ 316 | if(col == 0) { 317 | 318 | /* Print line numbers */ 319 | if(flags & FLAG_N) { 320 | printf("%5d ", line++); 321 | 322 | col += 6; 323 | } 324 | } 325 | 326 | /* New line ? */ 327 | if(ch == '\n') { 328 | putchar('\n'); 329 | 330 | col = 0; 331 | 332 | return; 333 | } 334 | 335 | /* Tab ? */ 336 | if(ch == '\t') { 337 | if(flags & FLAG_T) { 338 | k = tab_spaces - (col % tab_spaces); 339 | 340 | /* Max. width ? */ 341 | if(flags & FLAG_W) { 342 | if(col + k >= width) { 343 | tx_out('\n'); 344 | tx_out('\t'); 345 | 346 | return; 347 | } 348 | } 349 | 350 | col += k; 351 | 352 | while(k--) { 353 | putchar(' '); 354 | } 355 | 356 | return; 357 | } 358 | } 359 | 360 | /* Max. width ? */ 361 | if(flags & FLAG_W) { 362 | if(col + 1 > width) { 363 | tx_out('\n'); 364 | tx_out(ch); 365 | 366 | return; 367 | } 368 | } 369 | 370 | /* Print character */ 371 | putchar(ch); 372 | 373 | ++col; 374 | } 375 | 376 | /* Show usage and exit 377 | ------------------- 378 | */ 379 | usage() 380 | { 381 | fprintf(stderr, "%s %s - %s\n\n", APP_NAME, APP_VERSION, APP_COPYRGT); 382 | fprintf(stderr, "%s\n\n", APP_INFO); 383 | fprintf(stderr, "Usage:\n\t%s\n\n", APP_USAGE); 384 | 385 | fprintf( 386 | stderr, 387 | "Options:\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\n", 388 | APP_OPT_E, 389 | APP_OPT_L, 390 | APP_OPT_N, 391 | APP_OPT_T, 392 | APP_OPT_U, 393 | APP_OPT_W, 394 | APP_OPT_S 395 | ); 396 | 397 | fprintf(stderr, "Examples:\n\t%s\n\t%s\n", 398 | APP_EX_1, 399 | APP_EX_2 400 | ); 401 | 402 | exit(0); 403 | } 404 | 405 | /* Print error and exit 406 | -------------------- 407 | */ 408 | error(msg) 409 | char *msg; 410 | { 411 | fprintf(stderr, "%s: %s.\n", APP_NAME, msg); 412 | 413 | exit(-1); 414 | } 415 | 416 | /* Print error and exit 417 | -------------------- 418 | */ 419 | error_fname(msg, fname) 420 | char *msg, *fname; 421 | { 422 | fprintf(stderr, "%s: %s \"%s\".\n", APP_NAME, msg, fname); 423 | 424 | exit(-1); 425 | } 426 | 427 |  -------------------------------------------------------------------------------- /te_edit.c: -------------------------------------------------------------------------------- 1 | /* te_edit.c 2 | 3 | Text editor. 4 | 5 | Edit line. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 30 Jan 2018 : Extracted from te.c. 26 | 04 Feb 2018 : Support for macros. Go to line #. 27 | 22 Feb 2018 : Check for buffer changes. 28 | 26 Dec 2018 : Use TAB_COLS instead of 8. 29 | 06 Jan 2019 : Speed improvements. Now cut deletes the line. Now paste inserts a new line before the current one. 30 | 08 Jan 2019 : BfEdit() now uses ModifyLine(). 31 | 13 Jan 2019 : Minor optimizations. 32 | 18 Jan 2019 : Unselect block if needed. 33 | 18 Jan 2018 : Added K_DELETE. 34 | 27 Jan 2019 : Added support for macros. 35 | 29 Jan 2019 : Added K_CLRCLP. 36 | 24 Dec 2019 : Added support for line numbers. 37 | 26 Dec 2019 : Now K_INTRO is K_CR. 38 | 01 Mar 2020 : Added CLANG support. Set fe_forced flag in ForceGetCh(). 39 | 04 Jan 2021 : Use configuration variables. 40 | 25 Sep 2021 : Ignore '\0' characters comming from macro comments. Use editln variable. 41 | */ 42 | 43 | /* Edit current line 44 | ----------------- 45 | Returns last character entered. 46 | */ 47 | BfEdit() 48 | { 49 | int i, ch, len, run, upd_lin, upd_col, upd_now, upd_cur, spc, old_len; 50 | char *buf; 51 | 52 | /* Tell we are editing */ 53 | editln = 1; 54 | 55 | /* Get current line contents */ 56 | strcpy(ln_dat, lp_arr[lp_cur]); 57 | 58 | /* Setup some things */ 59 | len = old_len = strlen(ln_dat); 60 | 61 | run = upd_col = upd_now = upd_cur = 1; upd_lin = spc = 0; 62 | 63 | /* Adjust column position */ 64 | if(box_shc > len) 65 | box_shc = len; 66 | 67 | /* Loop */ 68 | while(run) 69 | { 70 | /* Print line? */ 71 | if(upd_lin) 72 | { 73 | upd_lin = 0; 74 | 75 | putstr(ln_dat + box_shc); 76 | 77 | /* Print a space? */ 78 | if(spc) 79 | { 80 | putchr(' '); spc = 0; 81 | } 82 | } 83 | 84 | /* Print length? */ 85 | if(upd_now) 86 | { 87 | upd_now = 0; 88 | 89 | CrtLocate(PS_ROW, PS_COL_NOW); putint("%02d", len); 90 | } 91 | 92 | /* Print column #? */ 93 | if(upd_col) 94 | { 95 | upd_col = 0; 96 | 97 | CrtLocate(PS_ROW, PS_COL_CUR); putint("%02d", box_shc + 1); 98 | } 99 | 100 | /* Locate cursor? */ 101 | if(upd_cur) 102 | { 103 | upd_cur = 0; 104 | 105 | CrtLocate(BOX_ROW + box_shr, box_shc + cf_num); 106 | } 107 | 108 | /* Get character and do action */ 109 | #if OPT_MACRO 110 | while((ch = ForceGetCh()) == 0) 111 | ; 112 | #else 113 | ch = ForceGetCh(); 114 | #endif 115 | 116 | #if OPT_BLOCK 117 | 118 | /* Unselect block if needed: don't check blk_count, we want to unselect start and / or end block selection */ 119 | if(blk_start != -1 || blk_end != -1) { 120 | if(ch < 1000) { 121 | upd_cur = 1; 122 | } 123 | else { 124 | switch(ch) 125 | { 126 | case K_CR : 127 | case K_TAB : 128 | case K_LDEL : 129 | case K_RDEL : 130 | case K_PASTE : 131 | case K_MACRO : 132 | upd_cur = 1; 133 | break; 134 | } 135 | } 136 | 137 | if(upd_cur) { 138 | LoopBlkUnset(); 139 | 140 | CrtLocate(BOX_ROW + box_shr, box_shc + cf_num); 141 | 142 | upd_cur = 0; 143 | } 144 | } 145 | 146 | #endif 147 | 148 | if(ch < 1000) 149 | { 150 | if(len < ln_max) 151 | { 152 | putchr(ch); 153 | 154 | for(i = len; i > box_shc; --i) 155 | { 156 | ln_dat[i] = ln_dat[i - 1]; 157 | } 158 | 159 | ln_dat[box_shc++] = ch; ln_dat[++len] = 0; 160 | 161 | ++upd_lin; ++upd_now; ++upd_col; 162 | 163 | if(cf_clang) { 164 | #if OPT_MACRO 165 | if(!MacroRunning()) 166 | { 167 | #endif 168 | switch(ch) 169 | { 170 | case '[' : ForceChLeft(len, ']'); break; 171 | case '{' : ForceChLeft(len, '}'); break; 172 | case '(' : ForceChLeft(len, ')'); break; 173 | case '"' : ForceChLeft(len, '"'); break; 174 | case '\'' : ForceChLeft(len, '\''); break; 175 | case '*' : if(box_shc > 1 && ln_dat[box_shc - 2] == '/' && len + 1 < ln_max) { ForceStr("*/"); ForceCh(K_LEFT); ForceCh(K_LEFT);} break; 176 | } 177 | #if OPT_MACRO 178 | } 179 | #endif 180 | } 181 | } 182 | 183 | ++upd_cur; 184 | } 185 | else 186 | { 187 | /* Note: This function does preliminary checks in some 188 | keys for Loop(), to avoid wasted time. */ 189 | switch(ch) 190 | { 191 | case K_LEFT : /* Move one character to the left -------- */ 192 | if(box_shc) 193 | { 194 | --box_shc; ++upd_col; 195 | } 196 | else if(lp_cur) 197 | { 198 | box_shc = 9999 /* strlen(lp_arr[lp_cur - 1]) */ ; 199 | 200 | ch = K_UP; 201 | 202 | run = 0; 203 | } 204 | ++upd_cur; 205 | break; 206 | case K_RIGHT : /* Move one character to the right ------- */ 207 | if(box_shc < len) 208 | { 209 | ++box_shc; ++upd_col; 210 | } 211 | else if(lp_cur < lp_now - 1) 212 | { 213 | ch = K_DOWN; 214 | 215 | box_shc = run = 0; 216 | } 217 | ++upd_cur; 218 | break; 219 | case K_LDEL : /* Delete one character to the left ------- */ 220 | if(box_shc) 221 | { 222 | strcpy(ln_dat + box_shc - 1, ln_dat + box_shc); 223 | 224 | --box_shc; --len; ++upd_now; ++upd_lin; ++spc; ++upd_col; 225 | 226 | putchr('\b'); 227 | } 228 | else if(lp_cur) 229 | run = 0; 230 | ++upd_cur; 231 | break; 232 | case K_RDEL : /* Delete one character to the right ----- */ 233 | if(box_shc < len) 234 | { 235 | strcpy(ln_dat + box_shc, ln_dat + box_shc + 1); 236 | 237 | --len; ++upd_now; ++upd_lin; ++spc; 238 | } 239 | else if(lp_cur < lp_now -1) 240 | run = 0; 241 | ++upd_cur; 242 | break; 243 | case K_UP : /* Up one line --------------------------- */ 244 | if(lp_cur) 245 | run = 0; 246 | ++upd_cur; 247 | break; 248 | case K_DOWN : /* One line down ------------------------- */ 249 | if(lp_cur < lp_now - 1) 250 | run = 0; 251 | ++upd_cur; 252 | break; 253 | #if OPT_BLOCK 254 | case K_BLK_START : /* Set block start -------------------- */ 255 | case K_BLK_END : /* Set block end ---------------------- */ 256 | case K_BLK_UNSET : /* Unset block ----------------------- */ 257 | #endif 258 | 259 | #if OPT_GOTO 260 | case K_GOTO : /* Go to line # -------------------------- */ 261 | #endif 262 | 263 | #if OPT_MACRO 264 | case K_MACRO : /* Execute macro from file -------------- */ 265 | #endif 266 | case K_COPY : /* Copy block/line to the clipboard ------ */ 267 | case K_CUT : /* Copy and delete block/line ------------ */ 268 | case K_PASTE : /* Paste clipboard before the current line */ 269 | case K_DELETE : /* Delete block/line --------------------- */ 270 | case K_CLRCLP : /* Clear the clipboard ------------------- */ 271 | case K_ESC : /* Escape: Show the menu ----------------- */ 272 | case K_CR : /* Insert CR (split the line) ------------ */ 273 | run = 0; 274 | break; 275 | case K_PGUP : /* Page up ------------------------------- */ 276 | case K_TOP : /* Document top -------------------------- */ 277 | if(lp_cur || box_shc) 278 | run = 0; 279 | ++upd_cur; 280 | break; 281 | 282 | case K_PGDOWN : /* Page down ----------------------------- */ 283 | case K_BOTTOM : /* Document bottom ----------------------- */ 284 | if(lp_cur < lp_now - 1 || box_shc != len) 285 | run = 0; 286 | ++upd_cur; 287 | break; 288 | 289 | case K_BEGIN : /* Begin of line ------------------------- */ 290 | if(box_shc) 291 | { 292 | box_shc = 0; ++upd_col; 293 | } 294 | ++upd_cur; 295 | break; 296 | case K_END : /* End of line --------------------------- */ 297 | if(box_shc != len) 298 | { 299 | box_shc = len; ++upd_col; 300 | } 301 | ++upd_cur; 302 | break; 303 | case K_TAB : /* Insert TAB (spaces) ------------------- */ 304 | i = cf_tab_cols - box_shc % cf_tab_cols; 305 | 306 | while(i--) 307 | { 308 | if(ForceCh(' ')) 309 | break; 310 | } 311 | break; 312 | #if OPT_LWORD 313 | case K_LWORD : /* Move one word to the left ------------ */ 314 | 315 | if(box_shc) 316 | { 317 | /* Skip the current word if we are at its begining */ 318 | if(ln_dat[box_shc] != ' ' && ln_dat[box_shc - 1] == ' ') 319 | --box_shc; 320 | 321 | /* Skip spaces */ 322 | while(box_shc && ln_dat[box_shc] == ' ') 323 | --box_shc; 324 | 325 | /* Find the beginning of the word */ 326 | while(box_shc && ln_dat[box_shc] != ' ') 327 | { 328 | /* Go to the beginning of the word */ 329 | if(ln_dat[--box_shc] == ' ') 330 | { 331 | ++box_shc; break; 332 | } 333 | } 334 | 335 | ++upd_col; 336 | } 337 | 338 | ++upd_cur; 339 | 340 | break; 341 | #endif 342 | 343 | #if OPT_RWORD 344 | case K_RWORD : /* Move one word to the right ----------- */ 345 | 346 | /* Skip current word */ 347 | while(ln_dat[box_shc] && ln_dat[box_shc] != ' ') 348 | ++box_shc; 349 | 350 | /* Skip spaces */ 351 | while(ln_dat[box_shc] == ' ') 352 | ++box_shc; 353 | 354 | ++upd_col; ++upd_cur; 355 | 356 | break; 357 | #endif 358 | 359 | #if OPT_FIND 360 | case K_FIND : /* Find string -------------------------- */ 361 | run = 0; 362 | break; 363 | 364 | case K_NEXT : /* Find next string --------------------- */ 365 | if(find_str[0]) 366 | run = 0; 367 | break; 368 | #endif 369 | 370 | } 371 | } 372 | } 373 | 374 | /* Update changes if any */ 375 | 376 | if(len == old_len) 377 | { 378 | /* Check for changes */ 379 | if(memcmp(lp_arr[lp_cur], ln_dat, len)) 380 | { 381 | /* Update the changes */ 382 | strcpy(lp_arr[lp_cur], ln_dat); 383 | 384 | /* Changes are not saved */ 385 | lp_chg = 1; 386 | } 387 | } 388 | else { 389 | ModifyLine(lp_cur, ln_dat); /* FIX-ME: Re-print the line with old contents in case of error? */ 390 | 391 | /* Changes are not saved */ 392 | lp_chg = 1; 393 | } 394 | 395 | /* Tell we are not editing */ 396 | editln = 0; 397 | 398 | /* Return last character entered */ 399 | return ch; 400 | } 401 | 402 | 403 | /* Add a character to forced entry buffer 404 | -------------------------------------- 405 | Return Z on success, NZ on failure. 406 | */ 407 | ForceCh(ch) 408 | int ch; 409 | { 410 | if(fe_now < FORCED_MAX) 411 | { 412 | ++fe_now; 413 | 414 | if(fe_set == FORCED_MAX) 415 | fe_set = 0; 416 | 417 | fe_dat[fe_set++] = ch; 418 | 419 | return 0; 420 | } 421 | 422 | return -1; 423 | } 424 | 425 | /* Add a string to forced entry buffer 426 | ----------------------------------- 427 | Return Z on success, NZ on failure. 428 | */ 429 | ForceStr(s) 430 | char *s; 431 | { 432 | while(*s) 433 | { 434 | if(ForceCh(*s++)) 435 | return -1; 436 | } 437 | 438 | return 0; 439 | } 440 | 441 | /* Return character from forced entry buffer, or keyboard 442 | ------------------------------------------------------ 443 | */ 444 | ForceGetCh() 445 | { 446 | if(fe_now) 447 | { 448 | --fe_now; 449 | 450 | if(fe_get == FORCED_MAX) 451 | fe_get = 0; 452 | 453 | fe_forced = 1; 454 | 455 | return fe_dat[fe_get++]; 456 | } 457 | 458 | #if OPT_MACRO 459 | 460 | if(MacroRunning()) { 461 | MacroGet(); 462 | 463 | if(fe_now) { 464 | return ForceGetCh(); 465 | } 466 | } 467 | 468 | #endif 469 | 470 | fe_forced = 0; 471 | 472 | return getchr(); 473 | } 474 | 475 | /* Single character completion for C language, etc. 476 | ------------------------------------------------ 477 | */ 478 | ForceChLeft(len, ch) 479 | int len, ch; 480 | { 481 | if(!fe_forced) 482 | { 483 | if(len < ln_max) 484 | { 485 | ForceCh(ch); ForceCh(K_LEFT); 486 | } 487 | } 488 | } 489 | 490 |  -------------------------------------------------------------------------------- /te_ui.c: -------------------------------------------------------------------------------- 1 | /* te_ui.c 2 | 3 | Text editor. 4 | 5 | User interface. 6 | 7 | Copyright (c) 2015-2021 Miguel Garcia / FloppySoftware 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the 11 | Free Software Foundation; either version 2, or (at your option) any 12 | later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 22 | 23 | Changes: 24 | 25 | 30 Jan 2018 : Extracted from te.c. 26 | 22 Feb 2018 : Ask for confirmation only if changes were not saved. INTRO equals Y on confirmation. 27 | 16 Jan 2019 : Modified Refresh() to show block selection. Added RefreshBlock(). 28 | 19 Jan 2019 : Added ShowFilename(). 29 | 23 Jan 2019 : Refactorized MenuHelp(). 30 | 30 Jan 2019 : Added putchrx(). 31 | 24 Dec 2019 : Modified some text messages. SysLineKey() is now SysLineCont(). Added support for numbered lines. 32 | 26 Dec 2019 : Now K_INTRO is K_CR. Add SysLineWait(), SysLineBack(). 33 | 28 Feb 2020 : Minor changes. 34 | 08 Mar 2020 : Support for CRT_LONG in menu, about and (ejem) help options. 35 | 31 Dec 2020 : Use NUM_SEP instead of space to separate line numbers from text. 36 | 04 Jan 2021 : Use configuration variables. 37 | 22 Feb 2021 : Removed CRT_ROWS, CRT_COLS. 38 | 04 Apr 2021 : Remove customized key names. Use key bindings from configuration. 39 | 05 Apr 2021 : Adapt HELP to last changes. 40 | 06 Apr 2021 : Use special screen characters from configuration instead of macros. 41 | 08 Apr 2021 : Get adaptation (port) name from configuration. 42 | 05 Jul 2021 : Support for OPT_Z80. 43 | 25 Sep 2021 : Added SysLineEdit(). Fix URLs. 44 | 01 Nov 2021 : Added menu option when macros are enabled: insert file. 45 | */ 46 | 47 | /* Read character from keyboard 48 | ---------------------------- 49 | */ 50 | /* **************************** SEE #define 51 | getchr() 52 | { 53 | return GetKey(); 54 | } 55 | ******************************* */ 56 | 57 | /* Print character on screen 58 | ------------------------- 59 | */ 60 | /* **************************** SEE #define 61 | putchr(ch) 62 | int ch; 63 | { 64 | CrtOut(ch); 65 | } 66 | ******************************* */ 67 | 68 | /* Print character on screen X times 69 | --------------------------------- 70 | */ 71 | #if OPT_Z80 72 | /* putchrx(ch, n) */ 73 | /* int ch, n; */ 74 | #asm 75 | putchrx: 76 | pop bc 77 | pop de 78 | pop hl 79 | push hl 80 | push de 81 | push bc 82 | 83 | putchrx1: 84 | ld a,d 85 | or e 86 | ret z 87 | 88 | dec de 89 | 90 | push de 91 | push hl 92 | 93 | call CrtOut 94 | 95 | pop hl 96 | pop de 97 | 98 | jr putchrx1 99 | #endasm 100 | #else 101 | putchrx(ch, n) 102 | int ch, n; 103 | { 104 | while(n--) { 105 | putchr(ch); 106 | } 107 | } 108 | #endif 109 | 110 | /* Print string on screen 111 | ---------------------- 112 | */ 113 | #if OPT_Z80 114 | /* putstr(s) */ 115 | /* char *s; */ 116 | #asm 117 | putstr: 118 | pop bc 119 | pop hl 120 | push hl 121 | push bc 122 | 123 | putstr1: 124 | ld a,(hl) 125 | or a 126 | ret z 127 | 128 | inc hl 129 | push hl 130 | 131 | ld h,0 132 | ld l,a 133 | push hl 134 | 135 | call CrtOut 136 | 137 | pop de 138 | pop hl 139 | 140 | jr putstr1 141 | #endasm 142 | #else 143 | putstr(s) 144 | char *s; 145 | { 146 | while(*s) 147 | putchr(*s++); 148 | } 149 | #endif 150 | 151 | /* Print string + '\n' on screen 152 | ----------------------------- 153 | */ 154 | putln(s) 155 | char *s; 156 | { 157 | putstr(s); putchr('\n'); 158 | } 159 | 160 | /* Print number on screen 161 | ---------------------- 162 | */ 163 | putint(format, value) 164 | char *format; int value; 165 | { 166 | char r[7]; /* -12345 + ZERO */ 167 | 168 | sprintf(r, format, value); 169 | 170 | putstr(r); 171 | } 172 | 173 | /* Print program layout 174 | -------------------- 175 | */ 176 | Layout() 177 | { 178 | int i, k, w; 179 | 180 | /* Clear screen */ 181 | CrtClear(); 182 | 183 | /* Header */ 184 | putstr("te:"); 185 | 186 | /* Information layout */ 187 | CrtLocate(PS_ROW, PS_INF); putstr(PS_TXT); 188 | 189 | /* Max. # of lines */ 190 | CrtLocate(PS_ROW, PS_LIN_MAX); putint("%04d", cf_mx_lines); 191 | 192 | /* # of columns */ 193 | CrtLocate(PS_ROW, PS_COL_MAX); putint("%02d", 1 + ln_max); 194 | 195 | /* Ruler */ 196 | #if CRT_LONG 197 | CrtLocate(BOX_ROW - 1, cf_num); 198 | 199 | w = cf_cols - cf_num; 200 | 201 | for(i = k = 0; i < w; ++i) 202 | { 203 | if(k++) 204 | { 205 | putchr(cf_rul_chr); 206 | 207 | if(k == cf_tab_cols) 208 | k = 0; 209 | } 210 | else 211 | putchr(cf_rul_tab); 212 | } 213 | 214 | /* System line separator */ 215 | CrtLocate(cf_rows - 2, 0); 216 | 217 | putchrx(cf_horz_chr, cf_cols); 218 | #endif 219 | } 220 | 221 | /* Print filename 222 | -------------- 223 | */ 224 | ShowFilename() 225 | { 226 | char *s; 227 | 228 | CrtLocate(PS_ROW, PS_FNAME); 229 | 230 | putstr((s = CurrentFile())); 231 | 232 | putchrx(' ', FILENAME_MAX - strlen(s) - 1); 233 | } 234 | 235 | /* Print message on system line 236 | ---------------------------- 237 | Message can be NULL == blank line / clear system line. 238 | */ 239 | SysLine(s) 240 | char *s; 241 | { 242 | CrtClearLine(cf_rows - 1); 243 | 244 | if(s) 245 | putstr(s); 246 | 247 | /* Set flag for Loop() */ 248 | sysln = 1; 249 | } 250 | 251 | /* Print message when editing 252 | -------------------------- 253 | */ 254 | SysLineEdit() 255 | { 256 | SysLine(GetKeyName(K_ESC)); putstr(" = menu"); 257 | } 258 | 259 | /* Print message on system line and wait 260 | for CR and / or ESC key press 261 | ------------------------------------- 262 | Message can be NULL. Returns NZ if CR, else Z. 263 | */ 264 | SysLineWait(s, cr, esc) 265 | char *s, *cr, *esc; 266 | { 267 | int ch; 268 | 269 | SysLine(s); 270 | 271 | if(s) 272 | putstr(" ("); 273 | 274 | if(cr) 275 | { 276 | putstr(GetKeyName(K_CR)); putstr(" = "); putstr(cr); putstr(", "); 277 | } 278 | 279 | if(esc) 280 | { 281 | putstr(GetKeyName(K_ESC)); putstr(" = "); putstr(esc); 282 | } 283 | 284 | if(s) 285 | putchr(')'); 286 | 287 | putstr(": "); 288 | 289 | for(;;) 290 | { 291 | ch = getchr(); 292 | 293 | if(cr && ch == K_CR) 294 | break; 295 | 296 | if(esc && ch == K_ESC) 297 | break; 298 | } 299 | 300 | SysLine(NULL); 301 | 302 | return (ch == K_CR); 303 | } 304 | 305 | 306 | /* Print message on system line and wait 307 | for ESC key press to CONTINUE 308 | ------------------------------------- 309 | Message can be NULL. 310 | */ 311 | SysLineCont(s) 312 | char *s; 313 | { 314 | SysLineWait(s, NULL, "continue"); 315 | } 316 | 317 | /* Print message on system line and wait 318 | for ESC key press to COMEBACK 319 | ------------------------------------- 320 | Message can be NULL. 321 | */ 322 | SysLineBack(s) 323 | char *s; 324 | { 325 | SysLineWait(s, NULL, "back"); 326 | } 327 | 328 | /* Print message on system line and wait 329 | for CONFIRMATION 330 | ------------------------------------- 331 | Message can be NULL. Returns NZ if YES, else Z. 332 | */ 333 | SysLineConf(s) 334 | char *s; 335 | { 336 | return SysLineWait(s, "continue", "cancel"); 337 | } 338 | 339 | /* Ask for a string 340 | ---------------- 341 | Return NZ if entered, else Z. 342 | */ 343 | SysLineStr(what, buf, maxlen) 344 | char *what, *buf; int maxlen; 345 | { 346 | int ch; 347 | 348 | SysLine(what); 349 | putstr(" ("); 350 | putstr(GetKeyName(K_ESC)); 351 | putstr(" = cancel): "); 352 | 353 | ch = ReadLine(buf, maxlen); 354 | 355 | SysLine(NULL); 356 | 357 | if(ch == K_CR && *buf) 358 | return 1; 359 | 360 | return 0; 361 | } 362 | 363 | /* Ask for a filename 364 | ------------------ 365 | Return NZ if entered, else Z. 366 | */ 367 | SysLineFile(fn) 368 | char *fn; 369 | { 370 | return SysLineStr("Filename", fn, FILENAME_MAX - 1); 371 | } 372 | 373 | /* Ask for confirmation on changes not saved 374 | ----------------------------------------- 375 | Returns NZ if YES, else Z. 376 | */ 377 | SysLineChanges() 378 | { 379 | return SysLineConf("Changes will be lost!"); 380 | } 381 | 382 | /* Read simple line 383 | ---------------- 384 | Returns last character entered: INTRO or ESC. 385 | */ 386 | ReadLine(buf, width) 387 | char *buf; 388 | int width; 389 | { 390 | int len; 391 | int ch; 392 | 393 | putstr(buf); len=strlen(buf); 394 | 395 | while(1) 396 | { 397 | switch((ch = getchr())) 398 | { 399 | case K_LDEL : 400 | if(len) 401 | { 402 | putchr('\b'); putchr(' '); putchr('\b'); 403 | 404 | --len; 405 | } 406 | break; 407 | case K_CR : 408 | case K_ESC : 409 | buf[len] = 0; 410 | return ch; 411 | default : 412 | if(len < width && ch >= ' ') 413 | putchr(buf[len++] = ch); 414 | break; 415 | } 416 | } 417 | } 418 | 419 | /* Return name of current file 420 | --------------------------- 421 | */ 422 | CurrentFile() 423 | { 424 | return (file_name[0] ? file_name : "-"); 425 | } 426 | 427 | /* Clear the editor box 428 | -------------------- 429 | */ 430 | ClearBox() 431 | { 432 | int i; 433 | 434 | for(i = 0; i < box_rows; ++i) 435 | CrtClearLine(BOX_ROW + i); 436 | } 437 | 438 | /* Print centered text on the screen 439 | --------------------------------- 440 | */ 441 | CenterText(row, txt) 442 | int row; char *txt; 443 | { 444 | CrtLocate(row, (cf_cols - strlen(txt)) / 2); 445 | 446 | putstr(txt); 447 | } 448 | 449 | #if OPT_BLOCK 450 | 451 | /* Refresh block selection in editor box 452 | ------------------------------------- 453 | Set 'sel' to NZ for reverse print, else Z for normal print. 454 | */ 455 | RefreshBlock(row, sel) 456 | int row, sel; 457 | { 458 | int i, line; 459 | 460 | line = GetFirstLine() + row; 461 | 462 | for(i = row; i < box_rows; ++i) { 463 | if(line >= blk_start) { 464 | if(line <= blk_end) { 465 | #if CRT_CAN_REV 466 | CrtLocate(BOX_ROW + i, cf_num); 467 | CrtClearEol(); 468 | 469 | if(sel) { 470 | CrtReverse(1); 471 | } 472 | 473 | putstr(lp_arr[line]); 474 | putchr(' '); 475 | 476 | if(sel) { 477 | 478 | CrtReverse(0); 479 | } 480 | #else 481 | CrtLocate(BOX_ROW + i, cf_cols - 1); putchr(sel ? BLOCK_CHR : ' '); 482 | #endif 483 | } 484 | else { 485 | break; 486 | } 487 | } 488 | 489 | ++line; 490 | } 491 | } 492 | 493 | #endif 494 | 495 | /* Refresh editor box 496 | ------------------ 497 | Starting from box row 'row', line 'line'. 498 | */ 499 | Refresh(row, line) 500 | int row, line; 501 | { 502 | int i; 503 | char *format; 504 | 505 | #if OPT_BLOCK 506 | 507 | int blk, sel; 508 | 509 | blk = (blk_count && blk_start <= GetLastLine() && blk_end >= GetFirstLine()); 510 | sel = 0; 511 | 512 | #endif 513 | 514 | if(cf_num) { 515 | format = "%?d"; 516 | format[1] = '0' + cf_num - 1; 517 | } 518 | 519 | for(i = row; i < box_rows; ++i) 520 | { 521 | CrtClearLine(BOX_ROW + i); 522 | 523 | if(line < lp_now) { 524 | 525 | if(cf_num) { 526 | putint(format, line + 1); 527 | putchr(cf_lnum_chr); 528 | } 529 | 530 | #if OPT_BLOCK 531 | 532 | if(blk) { 533 | if(line >= blk_start) { 534 | if(line <= blk_end) { 535 | #if CRT_CAN_REV 536 | CrtReverse((sel = 1)); 537 | #else 538 | sel = 1; 539 | #endif 540 | } 541 | } 542 | } 543 | 544 | #endif 545 | 546 | putstr(lp_arr[line++]); 547 | 548 | #if OPT_BLOCK 549 | 550 | if(sel) { 551 | #if CRT_CAN_REV 552 | putchr(' '); 553 | 554 | CrtReverse((sel = 0)); 555 | #else 556 | sel = 0; 557 | 558 | CrtLocate(BOX_ROW + i, cf_cols - 1); putchr(BLOCK_CHR); 559 | #endif 560 | } 561 | 562 | #endif 563 | 564 | } 565 | } 566 | } 567 | 568 | /* Refresh editor box 569 | ------------------ 570 | */ 571 | RefreshAll() 572 | { 573 | Refresh(0, lp_cur - box_shr); 574 | } 575 | 576 | /* Show the menu 577 | ------------- 578 | Return NZ to quit program. 579 | */ 580 | Menu() 581 | { 582 | int run, row, stay, menu, ask; 583 | 584 | /* Setup some things */ 585 | run = stay = menu = ask = 1; 586 | 587 | /* Loop */ 588 | while(run) 589 | { 590 | /* Show the menu */ 591 | if(menu) 592 | { 593 | row = BOX_ROW + 1; 594 | 595 | ClearBox(); 596 | 597 | CenterText(row++, "OPTIONS"); 598 | row++; 599 | #if CRT_LONG 600 | CenterText(row++, "New"); 601 | CenterText(row++, "Open"); 602 | CenterText(row++, "Save"); 603 | CenterText(row++, "save As"); 604 | #if OPT_MACRO 605 | CenterText(row++, "Insert"); 606 | #endif 607 | CenterText(row++, "Help"); 608 | CenterText(row++, "aBout te"); 609 | CenterText(row , "eXit te"); 610 | #else 611 | #if OPT_MACRO 612 | CenterText(row++, "New Open Save Save As"); 613 | CenterText(row++, "Insert Help aBout te eXit te"); 614 | #else 615 | CenterText(row++, "New Open Save Save As"); 616 | CenterText(row++, "Help aBout te eXit te "); 617 | #endif 618 | #endif 619 | menu = 0; 620 | } 621 | 622 | /* Ask for option */ 623 | if(ask) 624 | { 625 | SysLine("Option ("); 626 | putstr(GetKeyName(K_ESC)); 627 | putstr(" = back): "); 628 | } 629 | else 630 | { 631 | ask = 1; 632 | } 633 | 634 | /* Do it */ 635 | switch(toupper(getchr())) 636 | { 637 | case 'N' : run = MenuNew(); break; 638 | case 'O' : run = MenuOpen(); break; 639 | case 'S' : run = MenuSave(); break; 640 | case 'A' : run = MenuSaveAs(); break; 641 | #if OPT_MACRO 642 | case 'I' : run = MenuInsert(); break; 643 | #endif 644 | case 'B' : MenuAbout(); menu = 1; break; 645 | case 'H' : MenuHelp(); menu = 1; break; 646 | case 'X' : run = stay = MenuExit(); break; 647 | case K_ESC : run = 0; break; 648 | default : ask = 0; break; 649 | } 650 | } 651 | 652 | /* Clear editor box */ 653 | ClearBox(); 654 | 655 | SysLine(NULL); 656 | 657 | /* Return NZ to quit the program */ 658 | return !stay; 659 | } 660 | 661 | /* Menu option: New 662 | ---------------- 663 | Return Z to quit the menu. 664 | */ 665 | MenuNew() 666 | { 667 | if(lp_chg) 668 | { 669 | if(!SysLineChanges()) 670 | return 1; 671 | } 672 | 673 | NewFile(); 674 | 675 | return 0; 676 | } 677 | 678 | /* Menu option: Open 679 | ----------------- 680 | Return Z to quit the menu. 681 | */ 682 | MenuOpen() 683 | { 684 | char fn[FILENAME_MAX]; 685 | 686 | if(lp_chg) 687 | { 688 | if(!SysLineChanges()) 689 | return 1; 690 | } 691 | 692 | fn[0] = 0; 693 | 694 | if(SysLineFile(fn)) 695 | { 696 | if(ReadFile(fn)) 697 | NewFile(); 698 | else 699 | strcpy(file_name, fn); 700 | 701 | return 0; 702 | } 703 | 704 | return 1; 705 | } 706 | 707 | /* Menu option: Save 708 | ----------------- 709 | Return Z to quit the menu. 710 | */ 711 | MenuSave() 712 | { 713 | if(!file_name[0]) 714 | return MenuSaveAs(); 715 | 716 | WriteFile(file_name); 717 | 718 | return 1; 719 | } 720 | 721 | /* Menu option: Save as 722 | -------------------- 723 | Return Z to quit the menu. 724 | */ 725 | MenuSaveAs() 726 | { 727 | char fn[FILENAME_MAX]; 728 | 729 | strcpy(fn, file_name); 730 | 731 | if(SysLineFile(fn)) 732 | { 733 | if(!WriteFile(fn)) 734 | strcpy(file_name, fn); 735 | 736 | return 0; 737 | } 738 | 739 | return 1; 740 | } 741 | 742 | #if OPT_MACRO 743 | 744 | /* Menu option: Insert 745 | ------------------- 746 | Return Z to quit the menu. 747 | */ 748 | MenuInsert() 749 | { 750 | char fn[FILENAME_MAX]; 751 | 752 | fn[0] = 0; 753 | 754 | if(SysLineFile(fn)) 755 | { 756 | return MacroRunFile(fn, 1); 757 | } 758 | 759 | return 1; 760 | } 761 | 762 | #endif 763 | 764 | /* Menu option: Help 765 | ----------------- 766 | */ 767 | MenuHelp() 768 | { 769 | int i, k; 770 | char *s; 771 | 772 | ClearBox(); 773 | 774 | CrtLocate(BOX_ROW + 1, 0); 775 | 776 | putln("HELP:\n"); 777 | 778 | #if CRT_LONG 779 | 780 | for(i = 0; help_items[i] != -1; ++i) { 781 | 782 | // 123456789012345 (15 characters) 783 | // BlkEnd ^B^E 784 | 785 | if((k = help_items[i])) { 786 | if(*(s = GetKeyWhat(k)) == '?') { 787 | k = 0; 788 | } 789 | } 790 | 791 | if(k) { 792 | putstr(s); putchrx(' ', 11 - strlen(s)); 793 | 794 | k -= 1000; 795 | 796 | MenuHelpCh(cf_keys[k]); 797 | MenuHelpCh(cf_keys_ex[k]); 798 | } 799 | else { 800 | putchrx(' ', 15); 801 | } 802 | 803 | if((i + 1) % 3) { 804 | putchr(' '); putchr(cf_vert_chr); putchr(' '); 805 | } 806 | else { 807 | putchr('\n'); 808 | } 809 | } 810 | 811 | #else 812 | 813 | putstr("Sorry, no help is available."); 814 | 815 | #endif 816 | 817 | SysLineBack(NULL); 818 | } 819 | 820 | MenuHelpCh(ch) 821 | int ch; 822 | { 823 | if(ch) { 824 | if(ch < 32 || ch == 0x7F) { 825 | putchr('^'); putchr(ch != 0x7F ? '@' + ch : '?'); 826 | } 827 | else { 828 | putchr(ch); putchr(' '); 829 | } 830 | } 831 | else { 832 | putchr(' '); putchr(' '); 833 | } 834 | } 835 | 836 | /* Menu option: About 837 | ------------------ 838 | */ 839 | MenuAbout() 840 | { 841 | int row; 842 | 843 | #if CRT_LONG 844 | row = BOX_ROW + 1; 845 | 846 | ClearBox(); 847 | 848 | CenterText(row++, "te - Text Editor"); 849 | row++; 850 | CenterText(row++, VERSION); 851 | row++; 852 | CenterText(row++, "Configured for"); 853 | CenterText(row++, cf_name); 854 | row++; 855 | CenterText(row++, COPYRIGHT); 856 | row++; 857 | CenterText(row++, "http://www.floppysoftware.es"); 858 | CenterText(row++, "https://cpm-connections.blogspot.com"); 859 | CenterText(row , "floppysoftware@gmail.com"); 860 | #else 861 | row = BOX_ROW; 862 | 863 | ClearBox(); 864 | 865 | CenterText(row++, "te - Text Editor"); 866 | CenterText(row++, VERSION); 867 | CenterText(row++, "Configured for"); 868 | CenterText(row++, cf_name); 869 | CenterText(row++, COPYRIGHT); 870 | CenterText(row++, "www.floppysoftware.es"); 871 | #endif 872 | 873 | SysLineBack(NULL); 874 | } 875 | 876 | /* Menu option: Quit program 877 | ------------------------- 878 | */ 879 | MenuExit() 880 | { 881 | if(lp_chg) 882 | { 883 | return !SysLineChanges(); 884 | } 885 | 886 | /* Quit program */ 887 | return 0; 888 | } 889 | 890 |  -------------------------------------------------------------------------------- /copying.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 675 Mass Ave, Cambridge, MA 02139, USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | Appendix: How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 19yy 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) 19yy name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Library General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | te 2 | == 3 | 4 | v1.73 / 20 Nov 2021 for CP/M 5 | 6 | (c) 2015-2021 Miguel Garcia / FloppySoftware 7 | 8 | [http://www.floppysoftware.es/](http://www.floppysoftware.es) 9 | 10 | Introduction 11 | ------------ 12 | 13 | The `te` text editor is small, humble and useful. 14 | 15 | It edits the full text in memory, so your system must leave enough 16 | free TPA for the text, after `te` is loaded and running. 17 | 18 | It's screen oriented, and can be easily adapted to a lot of computers. 19 | 20 | It's written in the C language, and there are ports for various 21 | operating systems: CP/M, DOS, Windows and GNU/Linux. 22 | 23 | I use [MESCC](https://github.com/MiguelVis/mescc) to compile it for CP/M 24 | and the Z80 cpu. 25 | 26 | ![te image](http://www.floppysoftware.es/images/cpm-te.jpg "te image") 27 | 28 | Command line 29 | ------------ 30 | 31 | It's simple (for the PCW adaptation; see below for the name of the rest 32 | of available adaptations): 33 | 34 | ``` 35 | te_pcw [filename] 36 | ``` 37 | 38 | Examples: 39 | 40 | ``` 41 | te_pcw - To start an empty document. 42 | te_pcw todo.txt - To edit the document 'todo.txt'. 43 | ``` 44 | 45 | You should rename the adaptation of your choice to simply `te`, because 46 | some CCP implementations (including the standard from CP/M), do not like 47 | the character `_` in filenames. 48 | 49 | 50 | The screen layout 51 | ----------------- 52 | 53 | Depending of the `te` adaptation, you could see a layout similar to: 54 | 55 | ``` 56 | te: TODO.TXT --- | Lin:0012/0029/0512 Col:08/76 Len:07 57 | !.......!.......!.......!.......!.......!.......!.......!.......!... 58 | 1|This is my TO-DO list for today: 59 | 2| - Wake up. 60 | 3| - Make coffee. 61 | 4| - Have a shower. 62 | 5| - Get dressed. 63 | 6| - Go work and: 64 | 7| 1. Revise email. 65 | 8| 2. Call Peter. 66 | 9| 3. Meet the boss. 67 | 10| 4. Plan tomorrow. 68 | 11| - Have lunch with Sarah. 69 | 12| - ... 70 | 13| 71 | 14| 72 | 15| 73 | 16| 74 | 17| 75 | 18| 76 | 19| 77 | 20| 78 | 21| 79 | ------------------------------------------------------------------------ 80 | ESC = menu 81 | ``` 82 | 83 | On the first screen line, you will see something like: 84 | 85 | ``` 86 | te: TODO.TXT - The file name of the document your are editing. 87 | ``` 88 | 89 | And something like: 90 | 91 | ``` 92 | --- | Lin:0015/0042/0512 Col:32/90 Len:36 93 | ``` 94 | 95 | The very first field, can have one of the following values: 96 | 97 | ``` 98 | --- Means the clipboard is empty. 99 | CLP Means the clipboard has data. 100 | ``` 101 | 102 | The numbers following 'Lin' are: 103 | 104 | ``` 105 | 0015 - The line number you are editing right now. 106 | 0042 - The current total number of lines. 107 | 0512 - The maximum number of lines. 108 | ``` 109 | 110 | The numbers following 'Col' are: 111 | 112 | ``` 113 | 32 - The column number on which you are. 114 | 90 - The number of screen columns. 115 | ``` 116 | 117 | And, finally, the number following 'Len' is: 118 | 119 | ``` 120 | 36 - The length of the current line. 121 | ``` 122 | 123 | On the last screen line, you will see program messages and questions. 124 | 125 | 126 | The options menu 127 | ---------------- 128 | 129 | You can enter to the menu, by pressing the `ESCAPE` key, as shown 130 | in the messages line: 131 | 132 | ``` 133 | ESC = menu 134 | ``` 135 | 136 | Note that the exact name of your `ESCAPE` key may differ, depending of 137 | the program configuration. 138 | 139 | The options are: 140 | 141 | ``` 142 | New - To start a new document 143 | Open - To open a document 144 | Save - To save the current document 145 | save As - To save the current document under another filename. 146 | Insert - To insert a text file into the current position. 147 | Help - To show the help screen. 148 | aBout te - To show some te information. 149 | eXit te - To quit the program. 150 | ``` 151 | 152 | You can select an option by pressing the character in uppercase. 153 | 154 | To leave the menu, you must press `ESCAPE`. 155 | 156 | If you select one of the options `New`, `Open` or `eXit`, and there are 157 | any changes that are not saved yet, te will ask you for confirmation 158 | before proceed. 159 | 160 | If you start a new document, the `Save` option will redirect to you to 161 | the `save As` option. 162 | 163 | The help screen will show the keyboard configuration (or key bindings 164 | if you prefer), which depends of the program configuration. 165 | 166 | For example, in the case of TE_WS100 (25x80 VT100 and WordStar keys) you 167 | could see something like this: 168 | 169 | ``` 170 | Up ^E | Down ^X | Indent ^I 171 | Left ^S | Right ^D | NewLine ^M 172 | Begin ^QS | End ^QD | Escape ^[ 173 | Top ^QR | Bottom ^QC | Macro ^QM 174 | PgUp ^C | PgDown ^R | 175 | WordLeft ^A | WordRight ^F | 176 | DelLeft ^H | DelRight ^G | 177 | BlockStart ^KB | BlockEnd ^KK | BlockUnset ^KU 178 | Cut ^Y | Copy ^O | Paste ^W 179 | Delete ^KY | ClearClip ^T | 180 | Find ^QF | FindNext ^L | GoLine ^J 181 | ``` 182 | 183 | 184 | The clipboard 185 | ------------- 186 | 187 | The clipboard contents is not cleared after file operations (new, open, 188 | save...). That makes possible to share text between files. 189 | 190 | But it's a good practice to clear the clipboard when you don't need it 191 | anymore, to free some memory. 192 | 193 | 194 | Key bindings 195 | ------------ 196 | 197 | As you can see in the help screen of example, there are some key 198 | bindings to perform actions when you are editing the file. 199 | 200 | The exact keys you must press to do an action, depend on the configuration 201 | you are running, but the meanings are the same: 202 | - Up, Down, Left, Right: to move the cursor one character at a time. 203 | - Begin, End: to move the cursor to the begin or the end of the 204 | current line. 205 | - Top, Bottom: to move the cursor to the begin or the end of the 206 | current file. 207 | - PgUp, PgDown: to move the cursor to the previous or next page. 208 | - WordLeft, WordRight: to move the cursor to the previous or next word. 209 | - DelLeft, DelRight: to delete the previous or next character. 210 | - Find, FindNext: to find a string or repeat the search. 211 | - GoLine: to go to a line number. 212 | - BlockStart: to mark the start of a block of lines. 213 | - BlockEnd: to mark the end of a block of lines. 214 | - BlockUnset: to unselect a block of lines. 215 | - Cut, Copy, Paste, Delete: to cut, copy, paste or delete a line 216 | or block of lines. 217 | - ClearClip: to clear the clipboard data. 218 | - Macro: to run a macro. 219 | - Indent: to insert spaces as indentation. Same as Tab. 220 | - NewLine: to insert a break or empty line. Same as Cr, Enter, Intro 221 | or Return. 222 | - Escape: to exit the menu or cancel an action. Same as Esc. 223 | 224 | Take into account that some actions could not be available in all te 225 | adaptations to save memory space. These actions are: WordLeft, WordRight, 226 | Find, FindNext, GoLine, BlockStart, BlockEnd, BlockUnset and Macro. 227 | 228 | If you miss one or more of the mentioned actions, you can edit the exact 229 | file of the te adaptation and recompile it to include them. 230 | 231 | 232 | Auto-completion 233 | --------------- 234 | 235 | If the text editor is configured with the C language type auto-completion 236 | option enabled, the input of some characters will cause the automatic input 237 | of some other: 238 | 239 | ``` 240 | [ --> ] 241 | { --> } 242 | ( --> ) 243 | " --> " 244 | ' --> ' 245 | /* --> */ 246 | ``` 247 | 248 | 249 | Auto-indentation 250 | ---------------- 251 | 252 | The text editor supports automatic indentation of lines, according 253 | to the indentation of the previous one. 254 | 255 | The indentation is done by inserting the same number of spaces of 256 | the previous line - ie: 257 | 258 | ``` 259 | This paragraph is 260 | indented, according to 261 | the first line. 262 | More indentation 263 | here. 264 | ``` 265 | 266 | 267 | Lists 268 | ----- 269 | 270 | The text editor supports automatic lists, when the first non blank 271 | character of the previous line is one of the "bullets" according 272 | to the configuration. 273 | 274 | As automatic indentation is supported, automatic multi level lists 275 | are possible - ie: 276 | 277 | ``` 278 | - Item #1 279 | - Item #2 280 | * Item #2a 281 | * Item #2b 282 | > Item #2b-1 283 | > Item #2b-2 284 | - Item #3 285 | ``` 286 | 287 | 288 | Macros 289 | ------ 290 | 291 | Macros are a powerful way to perform repetitive tasks at editing level. 292 | 293 | For example, you could create a macro with your signature to include it 294 | in every letter you write. 295 | 296 | Or, being a programmer, you could create a gdoc block macro to document 297 | your own C functions. 298 | 299 | Macros are not affected by default by auto-completion, auto-indentation 300 | or lists. 301 | 302 | Each time you want to run a macro, just press the corresponding key 303 | for the Macro action, enter the filename you choose when you saved it 304 | to disk, and press the key for the NewLine action. That's all. 305 | 306 | The default filetype for macro files is ".M". 307 | 308 | The filetype is only required when it's different. So, if you have 309 | saved a macro file as `JOIN.M`, you could just enter `JOIN`: 310 | 311 | ``` 312 | JOIN.M you could enter JOIN.M or just JOIN 313 | JOIN.MAC you must enter JOIN.MAC 314 | ``` 315 | 316 | There are some special symbols you can use in your macros: 317 | 318 | ``` 319 | {# comment} comments, they are ignored 320 | {Up} {Down} {Left} {Right} move the cursor one character at a time 321 | {Begin} {End} go to the begin / end of the current line 322 | {Top} {Bottom} go to the begin / end of the current file 323 | {NewLine} insert a break or empty line 324 | {Indent} insert spaces as indentation 325 | {DelLeft} {DelRight} delete the character at the left / right 326 | {Cut} {Copy} {Delete} operation over a line or block of lines 327 | {Paste} paste the clipboard contents 328 | {ClearClip} clear the clipboard data 329 | {BlockStart} {BlockEnd} mark the start / end of a block of lines 330 | {FileName} insert the current filename 331 | {AutoIndent} enable / disable automatic indentation 332 | {AutoList} enable / disable automatic list 333 | ``` 334 | 335 | The symbol names are case insensitive - ie: `{ClearClip}` and `{clearclip}` 336 | are the same. 337 | 338 | Additionally, you can repeat a symbol as in: 339 | 340 | ``` 341 | {up:12} 342 | ``` 343 | 344 | Auto indentation or auto list can be enabled by just using the symbol 345 | name or setting a repeat number of `1`: 346 | 347 | ``` 348 | {AutoList} 349 | {AutoList:1} 350 | ``` 351 | 352 | They can be disabled setting a repeat number of `0`: 353 | 354 | ``` 355 | {AutoIndent:0} 356 | ``` 357 | 358 | Take into account that line endings in the macro are not translated 359 | to NewLine actions. Use `{NewLine}` for that. 360 | 361 | If you need to insert the `{` or `}` characters in the text of the 362 | macro, just write them as `\{` and `\}`. 363 | 364 | For example, a macro to insert a banner at the top of the document, 365 | could be written as: 366 | 367 | ``` 368 | {# this is a macro example} 369 | {top}{newline}{up} 370 | =============={newline} 371 | FloppySoftware{newline} 372 | =============={newline} 373 | ``` 374 | 375 | Some macro files are included as examples: 376 | 377 | ``` 378 | HEADER.M Above example. 379 | JOINUP.M Join current line with the previous one. 380 | JOINDOWN.M Join current line with the next one. 381 | ``` 382 | 383 | There are some macros for the C language: 384 | 385 | ``` 386 | CFILE.M File documentation block for GDOC. 387 | CFUN.M Function documentation block for GDOC. 388 | CDO.M Snippet for "do / while". 389 | CFOR.M Snippet for "for". 390 | CIF.M Snippet for "if". 391 | CIFELSE.M Snippet for "if / else". 392 | CSWITCH.M Snippet for "switch". 393 | CWHILE.M Snippet for "while". 394 | ``` 395 | 396 | File backup 397 | ----------- 398 | 399 | Each time a file is saved, te does a backup of the previous file 400 | contents if it exists. 401 | 402 | It is renamed as `te.bkp`. 403 | 404 | 405 | Adaptations 406 | ----------- 407 | 408 | The program adaptation is done by editing a small source code file. 409 | 410 | In this file, you must specify some configuration values according 411 | to your preferences and / or system, and complete a few C 412 | language functions to clear the screen, etc. 413 | 414 | As there are some adaptations already done, it's possible that your 415 | machine is already included between them. 416 | 417 | If not, don't worry, you can start from a similar adaptation. 418 | 419 | See the source code files for more information. 420 | 421 | Current CP/M adaptations are: 422 | - `te_pcw` : Amstrad PCW and CP/M Plus (31x90 VT52 like terminal). 423 | - `te_cpc3` : Amstrad CPC and CP/M Plus (24x80 VT52 like terminal). 424 | - `te_spec` : Spectrum +3 and CP/M Plus (23x51 VT52 like terminal). 425 | - `te_mur` : K. Murakami's CP/M emulator (25x80 VT100/Ansi). 426 | - `te_tak` : Takeda Toshiya's CP/M emulator (25x80 VT100/Ansi). 427 | - `te_ws100`: Generic 25x80 VT100 and WordStar keys. 428 | - `te_kp` : Kaypro II, 4 and 10 (24x80 ADM-3A like terminal), 429 | contributed by Stephen S. Mitchell (thanks!). 430 | - `te_px8` : Epson PX-8 "Geneva". 431 | - `te_ansi` : Generic 25x80 ANSI terminal, including (translated) keyboard 432 | escape sequences. 433 | - `te_apple`: Apple II with SoftCard, a 24x80 SOROC IQ 120 / 140 terminal 434 | and WordStar keys. 435 | - `te_c128` : Commodore 128 and CP/M Plus (25x80 ADM-31/3A like terminal). 436 | - `te_sam` : SAM Coupe and Pro-Dos (24x80 VT52 like terminal). 437 | 438 | Adaptations for other OS are (they are not distributed yet): 439 | - Windows 32 bit (25x80), compiled with Pelles C 440 | and its 'conio.h' library. 441 | - DOS (25x80), compiled with Turbo C, and 442 | its 'conio.h' library. 443 | - GNU/Linux (24x80), compiled with GCC and ncurses. 444 | 445 | 446 | Configuration 447 | ------------- 448 | 449 | The `TECF` configuration tool is supplied in order to adjust 450 | some `TE` generic options to your taste, if needed (its use 451 | is totally optional): 452 | 453 | ``` 454 | TECF v1.21 / 13 Nov 2021 - (c) 2021 Miguel Garcia / FloppySoftware 455 | 456 | TE configuration tool. 457 | 458 | Usage: 459 | tecf action arguments... 460 | 461 | Actions: 462 | patch COM file from CF file: 463 | patch [[filename[.COM]] [filename[.CF]]] 464 | dump CF values from COM file: 465 | dump [filename[.COM]] [> filename.CF] 466 | print key codes: 467 | key 468 | ``` 469 | 470 | You can configure TE by using the `patch` action - ie: 471 | 472 | ``` 473 | tecf patch te.com myconf.cf 474 | ``` 475 | 476 | The standard file types (`COM`, `CF`) and filename (`TE`) are optionals, 477 | so you could patch `te.com` with `te.cf` just with the command: 478 | 479 | ``` 480 | tecf patch 481 | ``` 482 | 483 | Take into account that the disk has to be enough space for a temporary 484 | file with the exact size as TE. 485 | 486 | You can see the current configuration of TE by using 487 | the `dump` action - ie: 488 | 489 | ``` 490 | tecf dump 491 | ``` 492 | 493 | To save the configuration in a file just add a redirection (a `tecf` 494 | feature thanks to `MESCC`): 495 | 496 | ``` 497 | tecf dump > myconf.cf 498 | ``` 499 | 500 | The standard file type (`COM`) and filename (`TE`) are optionals. 501 | 502 | If you don't know the character/s assigned to a key, the `key` action 503 | will help you: 504 | 505 | ``` 506 | tecf key 507 | ``` 508 | 509 | For example: 510 | 511 | ``` 512 | TECF v1.21 / 13 Nov 2021 - (c) 2021 Miguel Garcia / FloppySoftware 513 | 514 | TE configuration tool. 515 | 516 | Press any key to get its code/s (SPACE = exit): 517 | 518 | Hex Dec Ctl Chr 519 | --- --- --- --- 520 | 61 97 a 521 | 04 4 ^D 522 | 0D 13 ^M 523 | 08 8 ^H 524 | E0 224 525 | 53 83 S 526 | 0D 13 ^M 527 | ``` 528 | 529 | A `CF` configuration file is just a text file with some key / value 530 | pairs, in a very similar way of `INI` and `conf` files in other 531 | systems. 532 | 533 | Just a few rules: 534 | - comments start with the `#` character. 535 | - empty lines are ignored. 536 | - strings can be surrounded by the `"` character. 537 | 538 | See my `CF` and `CF READER` projects for more information. 539 | 540 | Each adaptation is supplied and patched with an initial configuration 541 | file that includes key bindings, etc. 542 | 543 | You should create your own configuration files if needed. 544 | 545 | The current supported options are the following (see `TE.CF`): 546 | 547 | ``` 548 | # ======================================== 549 | # TE configuration file 550 | # ---------------------------------------- 551 | # IMPORTANT! This file is for TECF, the TE 552 | # configuration tool. 553 | # ======================================== 554 | 555 | # Configuration name 556 | #te.confName = "My own configuration" 557 | 558 | # Screen height: 8..255 or auto for CP/M 3 559 | #screen.rows = 25 560 | 561 | # Screen width: 64..255 or auto for CP/M 3 562 | #screen.columns = 80 563 | 564 | # Character for normal position in ruler 565 | #screen.rulerChar = "." 566 | 567 | # Character for tab stop position in ruler 568 | #screen.rulerTabChar = "!" 569 | 570 | # Character for vertical draws -- ie: help columns 571 | #screen.vertChar = "|" 572 | 573 | # Character for horizontal draws -- ie: status line 574 | #screen.horizChar = "-" 575 | 576 | # Character between line numbers and text 577 | screen.lineNumbersChar = " " 578 | 579 | # How many lines can edit: 256..4096 -- each 580 | # empty line occupies 2 bytes of RAM 581 | editor.maxLines = 512 582 | 583 | # How many columns (spaces) are a TAB: 1..16 584 | editor.tabSize = 4 585 | 586 | # Show line numbers: true / false 587 | editor.lineNumbers = true 588 | 589 | # C language type completion: [], {}, (), "", '', /**/ 590 | editor.c_language = true 591 | 592 | # Automatically indent a new line as the previous one 593 | editor.autoIndent = true 594 | 595 | # Automatically start a list when the first non blank 596 | # character in a line is one of "listBullets" -- max. 597 | # 7 characters in long 598 | editor.autoList = true 599 | editor.listBullets = "-*>" 600 | 601 | # Some keynames used in the UI 602 | #keyname.newLine = "ENTER" 603 | #keyname.escape = "ESC" 604 | 605 | # Key bindings, legal definitions are: 606 | # ^A -> Ctrl-A -> one control char. 607 | # ^A^X -> Ctrl-A, Ctrl-X -> two control chars. 608 | # ^AX -> Ctrl-A, X -> one control char., one char. 609 | # 610 | # Legal control characters are: 611 | # ^A..^Z ^[ ^\ ^] ^^ ^_ -> 1..31 612 | # ^? -> 127 613 | #key.up = "" 614 | #key.down = "" 615 | #key.left = "" 616 | #key.right = "" 617 | #key.begin = "" 618 | #key.end = "" 619 | #key.top = "" 620 | #key.bottom = "" 621 | #key.pgUp = "" 622 | #key.pgDown = "" 623 | #key.indent = "" 624 | #key.newLine = "" 625 | #key.escape = "" 626 | #key.delRight = "" 627 | #key.delLeft = "" 628 | #key.cut = "" 629 | #key.copy = "" 630 | #key.paste = "" 631 | #key.delete = "" 632 | #key.clearClip = "" 633 | #key.find = "" 634 | #key.findNext = "" 635 | #key.goLine = "" 636 | #key.wordLeft = "" 637 | #key.wordRight = "" 638 | #key.blockStart = "" 639 | #key.blockEnd = "" 640 | #key.blockUnset = "" 641 | #key.macro = "" 642 | ``` 643 | 644 | 645 | Text tool 646 | --------- 647 | 648 | The text editor is supplied with `TETX` a text tool in order to help you to process 649 | text files. 650 | 651 | ``` 652 | TETX v1.01 / 20 Nov 2021 - (c) 2021 Miguel Garcia / FloppySoftware 653 | 654 | TE text tool. 655 | 656 | Usage: 657 | tetx [-options...] [fname...] [> fname] 658 | 659 | Options: 660 | -e Skip empty lines. 661 | -l Convert to lowercase. 662 | -n Print line numbers. 663 | -t[N] Convert tab to spaces (default = 4). 664 | -u Convert to uppercase. 665 | -wN Max. width of lines (32..255). 666 | -s Trim spaces on the right. 667 | 668 | Examples: 669 | tetx -ne mydoc.txt 670 | tetx -t4u -n letter1.txt letter2.txt > letters.txt 671 | ``` 672 | 673 | The `-n` option will print the line number before each line: 674 | 675 | ``` 676 | 25 This is a text line, 677 | 26 and this is another one. 678 | ``` 679 | 680 | The `-t` option will convert tab characters to spaces, 681 | there is a tab each N columns: 682 | 683 | ``` 684 | + + + + + + + + 685 | This line does not have a tab. 686 | But this one has one. 687 | And this one has two. 688 | A tab here. 689 | ``` 690 | 691 | The `-w` option will split lines longer than N characters: 692 | 693 | ``` 694 | This is a line longer than 32 characters. 695 | ``` 696 | 697 | The command `tetx -w32` will process the line as: 698 | 699 | ``` 700 | This is a line longer than 32 ch 701 | aracters. 702 | ``` 703 | 704 | You can combine options as `-w32nu` or `-w32n -u`: 705 | 706 | ``` 707 | 1 THIS IS A TEXT WITH LINE N 708 | 2 UMBERS. IT HAS A MAXIMUM W 709 | 3 IDTH OF 32 CHARACTERS AND 710 | 4 IT HAS BEEN CONVERTED TO U 711 | 5 PPERCASE. 712 | ``` 713 | 714 | The output is written to `stdout` (the console). So, you 715 | must use output redirection to a file, in order to save 716 | the result: 717 | 718 | ``` 719 | tetx -w32nu draft.txt > final.txt 720 | ``` 721 | 722 | You can omit the input filename, in order to read the input 723 | from `stdin` (the console): 724 | 725 | ``` 726 | tetx -w32nu > letter.txt 727 | ``` 728 | 729 | Or you can combine two or more files (`-` means `stdin`): 730 | 731 | ``` 732 | tetx -w32nu header.txt body.txt footer.txt > letter.txt 733 | tetx -w32nu header.txt - footer.txt > letter.txt 734 | ``` 735 | 736 | 737 | License 738 | ------- 739 | 740 | This program is freeware, and it's licensed under the GNU GPL license. 741 | 742 | See the file `copying.txt` for more details. 743 | 744 | 745 | About this file 746 | --------------- 747 | 748 | Of course, this text file has been created and edited with te. 749 | --------------------------------------------------------------------------------