├── TOOLS ├── FASTKBD │ ├── FASTKBD.HEX │ ├── FASTKBD.COM │ ├── MAKEFILE │ └── FASTKBD.C-- ├── BIN2OBJ │ ├── BIN2OBJ.COM │ ├── MAKEFILE │ ├── OBJOMF.H-- │ ├── STDLIB.H-- │ ├── PRINT.H-- │ ├── OBJOMF.C-- │ ├── FILE.H-- │ ├── STR.H-- │ └── BIN2OBJ.C-- └── VGA3X │ ├── BIN │ ├── VGA30.COM │ └── VGA34.COM │ ├── SRC │ ├── MAKEFILE │ └── VGA3X.ASM │ ├── README.MD │ └── LICENSE ├── BIN ├── DWED.EXE ├── HLPC.EXE ├── BIN2OBJ.COM ├── DWEDOVL.EXE └── DWED.CFG ├── DWED-ASC.PNG ├── DWED-BAS.PNG ├── DWED-C.PNG ├── DWED-CLC.PNG ├── DWED-HLP.PNG ├── DWED-PAS.PNG ├── DWED-TXT.PNG ├── SRC ├── DWED.EXE ├── HLPC.EXE ├── BIN2OBJ.COM ├── DWEDHELP.OBJ ├── DWEDOVL.EXE ├── DWEDTBL.PAS ├── DWED.CFG ├── MAKEFILE ├── HLPC.PAS ├── DWEDLNCH.PAS ├── UNREDO.PAS ├── STRUTIL.PAS ├── EVENT.PAS ├── DWEDTYPE.PAS ├── DWEDHELP.PAS ├── DWED.TXT ├── DWEDHELP.HLP ├── DWED.C-- ├── DWEDSCRU.PAS ├── HELP.PAS ├── STRS.PAS ├── DWEDADDO.PAS ├── DWEDOVL.PAS ├── STRSDOS.PAS ├── SCR.PAS └── STRSSWAP.PAS ├── .github └── FUNDING.yml ├── LICENSE └── README.md /TOOLS/FASTKBD/FASTKBD.HEX: -------------------------------------------------------------------------------- 1 | 0000: B8 05 03 31 DB CD 16 C3 2 | -------------------------------------------------------------------------------- /BIN/DWED.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/BIN/DWED.EXE -------------------------------------------------------------------------------- /BIN/HLPC.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/BIN/HLPC.EXE -------------------------------------------------------------------------------- /DWED-ASC.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/DWED-ASC.PNG -------------------------------------------------------------------------------- /DWED-BAS.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/DWED-BAS.PNG -------------------------------------------------------------------------------- /DWED-C.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/DWED-C.PNG -------------------------------------------------------------------------------- /DWED-CLC.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/DWED-CLC.PNG -------------------------------------------------------------------------------- /DWED-HLP.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/DWED-HLP.PNG -------------------------------------------------------------------------------- /DWED-PAS.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/DWED-PAS.PNG -------------------------------------------------------------------------------- /DWED-TXT.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/DWED-TXT.PNG -------------------------------------------------------------------------------- /SRC/DWED.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/SRC/DWED.EXE -------------------------------------------------------------------------------- /SRC/HLPC.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/SRC/HLPC.EXE -------------------------------------------------------------------------------- /BIN/BIN2OBJ.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/BIN/BIN2OBJ.COM -------------------------------------------------------------------------------- /BIN/DWEDOVL.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/BIN/DWEDOVL.EXE -------------------------------------------------------------------------------- /SRC/BIN2OBJ.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/SRC/BIN2OBJ.COM -------------------------------------------------------------------------------- /SRC/DWEDHELP.OBJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/SRC/DWEDHELP.OBJ -------------------------------------------------------------------------------- /SRC/DWEDOVL.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/SRC/DWEDOVL.EXE -------------------------------------------------------------------------------- /SRC/DWEDTBL.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/SRC/DWEDTBL.PAS -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/BIN2OBJ.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/TOOLS/BIN2OBJ/BIN2OBJ.COM -------------------------------------------------------------------------------- /TOOLS/FASTKBD/FASTKBD.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/TOOLS/FASTKBD/FASTKBD.COM -------------------------------------------------------------------------------- /TOOLS/VGA3X/BIN/VGA30.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/TOOLS/VGA3X/BIN/VGA30.COM -------------------------------------------------------------------------------- /TOOLS/VGA3X/BIN/VGA34.COM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DosWorld/dwed/HEAD/TOOLS/VGA3X/BIN/VGA34.COM -------------------------------------------------------------------------------- /TOOLS/FASTKBD/MAKEFILE: -------------------------------------------------------------------------------- 1 | all: fastkbd.com 2 | 3 | fastkbd.com: fastkbd.c-- 4 | c-- /lst /x fastkbd.c-- 5 | -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/MAKEFILE: -------------------------------------------------------------------------------- 1 | all: BIN2OBJ.COM 2 | 3 | BIN2OBJ.COM: BIN2OBJ.C-- OBJOMF.C-- BSEEK.H-- FILE.H-- OBJOMF.H-- PRINT.H-- STDLIB.H-- STR.H-- 4 | C-- /X /0 BIN2OBJ.C-- 5 | -------------------------------------------------------------------------------- /TOOLS/VGA3X/SRC/MAKEFILE: -------------------------------------------------------------------------------- 1 | all: vga30.com vga34.com 2 | 3 | vga30.com: vga3x.asm 4 | nasm -f bin vga3x.asm -DVGA30 -o vga30.com 5 | 6 | vga34.com: vga3x.asm 7 | nasm -f bin vga3x.asm -DVGA34 -o vga34.com 8 | 9 | install: all 10 | copy vga3*.com ..\BIN 11 | 12 | clean: 13 | del vga30.com 14 | del vga34.com 15 | del *.bak 16 | -------------------------------------------------------------------------------- /BIN/DWED.CFG: -------------------------------------------------------------------------------- 1 | tab_size = 8 2 | color.top = 70 3 | color.top_hl = 74 4 | color.text = 07 5 | color.text_hl = 03 6 | color.text_dl = 08 7 | color.text_sel = 17 8 | color.menu = 70 9 | color.menu_sel = 1f 10 | color.help_menu = 07 11 | color.help_menu_sel = 70 12 | color.help = 07 13 | color.help_hl = 03 14 | usr.def.f5=dir 15 | usr.def.f8=c:\vc\vc 16 | usr.def.f9= 17 | hl.enable = 1 18 | memory=dos 19 | -------------------------------------------------------------------------------- /SRC/DWED.CFG: -------------------------------------------------------------------------------- 1 | tab_size = 8 2 | color.top = 70 3 | color.top_hl = 74 4 | color.text = 07 5 | color.text_hl = 03 6 | color.text_dl = 08 7 | color.text_sel = 17 8 | color.menu = 70 9 | color.menu_sel = 1f 10 | color.help_menu = 07 11 | color.help_menu_sel = 70 12 | color.help = 07 13 | color.help_hl = 03 14 | usr.def.f5=dir 15 | usr.def.f8=c:\vc\vc 16 | usr.def.f9= 17 | hl.enable = 1 18 | memory=swap 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: dosworld 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /TOOLS/VGA3X/README.MD: -------------------------------------------------------------------------------- 1 | # VGA3x 2 | 3 | Here are two resident programs that allow forcibly set VGA adapters 4 | to 30-line mode when trying to install via BIOS 2nd or 3rd video mode. 5 | 6 | VGA3x - checks the video mode setting, and if the 2nd or 3rd one is set, 7 | then independently sets the 30(34) line mode using VGA ports. 8 | 9 | When writing this program, the source code of the program was used 10 | VGA480 by Dmitry Gurtyak. 11 | 12 | Ways of changing the source texts to change the inline modes are 13 | indicated in the comments. 14 | 15 | Published in Softpanorama 1993, Vol 4(38). SP54A 16 | 17 | # License 18 | 19 | Public domain 20 | 21 | I am not author, just translate to english and Nasm. :) 22 | 23 | Original author: 24 | 25 | Vadim V.Belman, 26 | Dniepropetrovsk, 27 | Work phone : (0562)448-158 28 | Network 2:464/20.4@fidonet 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 DosWorld 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SRC/MAKEFILE: -------------------------------------------------------------------------------- 1 | all : dwed.exe dwedovl.exe 2 | 3 | dwed.exe: dwed.c-- 4 | c-- dwed.c-- 5 | 6 | debug: dwedovl.pas dwedtype.pas dwedhndl.pas dwedutil.pas strs.pas strsdos.pas strsswap.pas strssxms.pas dwedhl.pas dwedscru.pas dwedhelp.obj dwedhelp.pas dwedhelp.obj scr.pas scrui.pas help.pas strutil.pas kbd.pas dwedaddo.pas dwedlnch.pas mouse.pas event.pas dwedtbl.pas 7 | tpc -B -V -DDEBUG -$D+ -$L+ -$G- -$R- -$S- -$I- -$E- -$Q- -$B- dwedovl.pas 8 | 9 | dwedovl.exe: dwedovl.pas dwedtype.pas dwedhndl.pas dwedutil.pas strs.pas strsdos.pas strsswap.pas strssxms.pas dwedhl.pas dwedscru.pas dwedhelp.obj dwedhelp.pas dwedhelp.obj scr.pas scrui.pas help.pas strutil.pas kbd.pas dwedaddo.pas dwedlnch.pas mouse.pas event.pas dwedtbl.pas 10 | tpc -B -$D- -$L- -$G- -$R- -$S- -$I- -$E- -$Q- -$B- dwedovl.pas 11 | 12 | dwedhelp.hlp: dwed.txt hlpc.exe 13 | hlpc dwed.txt dwedhelp.hlp 14 | 15 | hlpc.exe: hlpc.pas help.pas 16 | tpc -B -$D- -$G- -$R- -$S- -$I- -$E- hlpc.pas 17 | lzexe hlpc.exe 18 | 19 | dwedhelp.obj: dwedhelp.hlp 20 | bin2obj dwedhelp.hlp dwedhelp.obj HELPBIN 21 | 22 | clean: 23 | del *.tpu 24 | del *.bak 25 | del *.obj 26 | del *.hlp 27 | -------------------------------------------------------------------------------- /TOOLS/VGA3X/LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /TOOLS/FASTKBD/FASTKBD.C--: -------------------------------------------------------------------------------- 1 | /* 2 | (c) 2019 Copyright by Viacheslav Komenda 3 | 4 | This is free and unencumbered software released into the public domain. 5 | Anyone is free to copy, modify, publish, use, compile, sell, or 6 | distribute this software, either in source code form or as a compiled 7 | binary, for any purpose, commercial or non-commercial, and by any 8 | means. 9 | 10 | In jurisdictions that recognize copyright laws, the author or authors 11 | of this software dedicate any and all copyright interest in the 12 | software to the public domain. We make this dedication for the benefit 13 | of the public at large and to the detriment of our heirs and 14 | successors. We intend this dedication to be an overt act of 15 | relinquishment in perpetuity of all present and future rights to this 16 | software under copyright law. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | For more information, please refer to 27 | 28 | */ 29 | ?parsecommandline FALSE 30 | ?resize FALSE 31 | 32 | void main() { 33 | AX=0x0305; BX = 0; $INT 0x16; 34 | } -------------------------------------------------------------------------------- /SRC/HLPC.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2022 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$M 30240, 128000, 128000} 23 | {$G-,F-,S-,R-,Q-} 24 | USES help, System2; 25 | 26 | BEGIN 27 | System.writeln('CP/M+ Help Compiler (c) DosWorld 2020 MIT License'); 28 | System.writeln; 29 | IF paramcount <> 2 THEN BEGIN 30 | System.writeln('Usage:'); 31 | System.writeln(#9+'HLPC infile.txt outfile.dat'); 32 | halt(1); 33 | END; 34 | compile(paramstr(1), paramstr(2)); 35 | halt(0); 36 | END. 37 | -------------------------------------------------------------------------------- /SRC/DWEDLNCH.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2022 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$A-,F-} 23 | unit dwedlnch; 24 | 25 | interface 26 | 27 | const 28 | EXEC_USER_CMD = 254; 29 | 30 | function is_installed : boolean; 31 | function get_temp_name : string; 32 | procedure set_exec_cmd(cmd : string); 33 | 34 | implementation 35 | 36 | uses dwedtype; 37 | 38 | var parent : pchar; 39 | ppsp : word; 40 | 41 | function is_installed : boolean; 42 | begin 43 | is_installed := PString(parent)^ = 'DWED'; 44 | end; 45 | 46 | function get_temp_name : string; 47 | begin 48 | get_temp_name := PString(parent + 5)^; 49 | end; 50 | 51 | procedure set_exec_cmd(cmd : string); 52 | begin 53 | PString(parent + 18)^ := ' /C ' + cmd + #0; 54 | end; 55 | 56 | begin 57 | ppsp := PWord(ptr(PrefixSeg, $16))^; 58 | parent := ptr(ppsp, PWord(ptr(ppsp, 5))^); 59 | end. 60 | -------------------------------------------------------------------------------- /SRC/UNREDO.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2022 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$A-} 23 | unit unredo; 24 | 25 | interface 26 | 27 | const 28 | ALINE : char = 'a'; 29 | RLINE : char = 'r'; 30 | 31 | procedure init; 32 | procedure done; 33 | 34 | implementation 35 | 36 | uses system2, str, dbm, dbb; 37 | 38 | type 39 | TString = record 40 | next : longint; 41 | prev : longint; 42 | utype : char; 43 | len : word; 44 | num : longint; 45 | recno : longint; 46 | end; 47 | 48 | const MEM_BLK_SIZE = 32; 49 | IDX_BLK_SIZE = sizeof(TString); 50 | 51 | var dbm_mem : DBMFile; 52 | dbb_idx : DBBFile; 53 | 54 | 55 | procedure init; 56 | begin 57 | FillChar(dbm_mem, SizeOf(DBMFile), #0); 58 | FillChar(dbb_idx, SizeOf(DBBFile), #0); 59 | dbm_rewritetemp(dbm_mem, MEM_BLK_SIZE); 60 | dbb_rewritetemp(dbb_idx, IDX_BLK_SIZE); 61 | end; 62 | 63 | procedure done; 64 | begin 65 | dbm_close(dbm_mem); 66 | dbb_close(dbb_idx); 67 | end; 68 | 69 | end. 70 | 71 | -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/OBJOMF.H--: -------------------------------------------------------------------------------- 1 | /* 2 | (c) 2019 Copyright by Viacheslav Komenda 3 | 4 | This is free and unencumbered software released into the public domain. 5 | 6 | Anyone is free to copy, modify, publish, use, compile, sell, or 7 | distribute this software, either in source code form or as a compiled 8 | binary, for any purpose, commercial or non-commercial, and by any 9 | means. 10 | 11 | In jurisdictions that recognize copyright laws, the author or authors 12 | of this software dedicate any and all copyright interest in the 13 | software to the public domain. We make this dedication for the benefit 14 | of the public at large and to the detriment of our heirs and 15 | successors. We intend this dedication to be an overt act of 16 | relinquishment in perpetuity of all present and future rights to this 17 | software under copyright law. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | For more information, please refer to 28 | 29 | */ 30 | 31 | #ifndef _OBJOMF_H_ 32 | #define _OBJOMF_H_ 33 | 34 | #define VERNUM 0xcc 35 | #define THEADR 0x80 36 | #define COMENT 0x88 37 | #define LNAMES 0x96 38 | #define LLNAMES 0xca 39 | #define SEGDEF16 0x98 40 | #define PUBDEF16 0x90 41 | #define GRPDEF 0x9a 42 | #define LEDATA16 0xa0 43 | #define FIXUPP16 0x9c 44 | #define MODEND16 0x8a 45 | #define LIDATA 0xa2 46 | #define EXTDEF 0x8c 47 | #define LHEADR 0xF0 48 | #define LFOOTR 0xF1 49 | #define SEG386 0x99 50 | 51 | #define SEGA_ABS 0 52 | #define SEGA_BYTE 0x20 53 | #define SEGA_WORD 0x40 54 | #define SEGA_PARA 0x60 55 | #define SEGA_PAGE 0x80 56 | 57 | #define SEGC_NOT 0 58 | #define SEGC_PUBLIC 0x08 59 | #define SEGC_STACK 0x14 60 | #define SEGC_COMMON 0x18 61 | 62 | #define SEGS_NOTBIG 0x00 63 | #define SEGS_BIG 0x02 64 | 65 | 66 | #define MA_NM_NS 0x01 67 | #define MA_NM_S 0x41 68 | #define MA_M_NS 0x81 69 | #define MA_M_S 0xC1 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/STDLIB.H--: -------------------------------------------------------------------------------- 1 | /* 2 | (c) 2019 Copyright by Viacheslav Komenda 3 | 4 | This is free and unencumbered software released into the public domain. 5 | Anyone is free to copy, modify, publish, use, compile, sell, or 6 | distribute this software, either in source code form or as a compiled 7 | binary, for any purpose, commercial or non-commercial, and by any 8 | means. 9 | 10 | In jurisdictions that recognize copyright laws, the author or authors 11 | of this software dedicate any and all copyright interest in the 12 | software to the public domain. We make this dedication for the benefit 13 | of the public at large and to the detriment of our heirs and 14 | successors. We intend this dedication to be an overt act of 15 | relinquishment in perpetuity of all present and future rights to this 16 | software under copyright law. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | For more information, please refer to 27 | 28 | */ 29 | 30 | #ifndef _STDLIB_H_ 31 | #define _STDLIB_H_ 32 | 33 | // EXIT(code); 34 | inline void EXIT() { AH=0x4C; $INT 0x21; } 35 | inline void ABORT() { AX=0x4C01; $INT 0x21; } 36 | 37 | void exit(int code) { EXIT(code); } 38 | void abort() { ABORT(); } 39 | 40 | enum { SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2}; 41 | 42 | char BSEEK(BX, DI, AL) { 43 | DX = DSWORD[DI]; 44 | CX = DSWORD[DI + 2]; 45 | AH = 0x42; 46 | $INT 0x21; 47 | IF (NOTCARRYFLAG) { 48 | AL = TRUE; 49 | } 50 | ELSE { AL = FALSE; } 51 | return (AL); 52 | } 53 | 54 | void BTELL(BX, DI) { 55 | $PUSH DI; 56 | AX = 0x4201; 57 | CX = DX = 0; 58 | $INT 0x21; 59 | $POP DI; 60 | DSWORD[DI] = AX; 61 | DSWORD[DI+2] = DX; 62 | } 63 | 64 | /* 65 | char bseek(word f; word pos; byte mode) { 66 | DI = pos; 67 | DX = DSWORD[DI]; 68 | CX = DSWORD[DI + 2]; 69 | BX = f; 70 | AL = mode; 71 | AH = 0x42; 72 | $INT 0x21; 73 | IF (NOTCARRYFLAG) { 74 | AL = TRUE; 75 | } 76 | ELSE { AL = FALSE; } 77 | return (AL); 78 | } 79 | 80 | void btell(word f; word pos) { 81 | BX = f; 82 | AX = 0x4201; 83 | CX = DX = 0; 84 | $INT 0x21; 85 | DI = pos; 86 | DSWORD[DI] = AX; 87 | DSWORD[DI+2] = DX; 88 | } 89 | */ 90 | 91 | void strcpy(word dst, word src) { 92 | $CLD; 93 | SI = src; 94 | DI = dst; 95 | WHILE(TRUE) { 96 | $LODSB; 97 | $STOSB; 98 | IF(AL==0) BREAK; 99 | } 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DWED 2 | 3 | Text file editor and IDE for MS-DOS and 8086/88 CPU (IBM XT-grade PC) designed in modern style. 4 | 5 | Main features: 6 | 7 | * Support files with size over 64kb (~300kb conventional, or up to 2gb swap) 8 | * Dont require DPMI-server or 80286 CPU, but support huge swap-file (could be placed on ramdisk) 9 | * Support basic syntax highlight (C/C++/C--, Pascal, Basic, Assembler, Xml/Html, text files etc) 10 | * Support multiple file editing at the same time 11 | * Support unix-like text files for open 12 | * Support Long File Names (LFN) 13 | * Support internal clipboard (size up to 32kb) 14 | * Support Windows Clipboard (you can use it with [clipdrv](https://github.com/DosWorld/clipdrv) or DosBox-X) 15 | * Support user's color scheme (via config-file) 16 | * Support user's shell script running by hotkeys **F5**, **F8**, **F9**. 17 | * You can disable highlight and receive good speed with XT. 18 | * Support mouse 19 | 20 | Restrictions: 21 | 22 | * This software is writen in Turbo Pascal, so string length is limited to 255 chars. 23 | * DWED don't parse file content in the same way, as compilers - so, some time syntax highlight can fail (be wrong). I know it. But it is better then nothing. 24 | * No Undo/Redo functionality. The reason is the same as why i dont build AST for syntax highlight - here is no memory/CPU speed for it. 25 | 26 | Here is small review/intro on FreeDOS channel: http://www.youtube.com/watch?v=7zFomGoKdlQ 27 | 28 | # How to run and use 29 | Use: 30 | 31 | C:\DWED\dwed.exe filename1 .. filenameN 32 | 33 | Use key **F1** to get more documentation (hotkeys, tips etc). I don't want write documentation and put all knowledge to buildin help. 34 | 35 | # Screenshots 36 | 37 | ### Text file highlight 38 | ![Image Screenshot - Txt syntax highlighjt](https://github.com/DosWorld/dwed/raw/main/DWED-TXT.PNG) 39 | 40 | ### Turbo Pascal syntax highlight 41 | ![Image Screenshot - Pascal syntax highlighjt](https://github.com/DosWorld/dwed/raw/main/DWED-PAS.PNG) 42 | 43 | ### Power Basic syntax highlight 44 | ![Image Screenshot - Basic syntax highlighjt](https://github.com/DosWorld/dwed/raw/main/DWED-BAS.PNG) 45 | 46 | ### C syntax highlight 47 | ![Image Screenshot - C syntax highlighjt](https://github.com/DosWorld/dwed/raw/main/DWED-C.PNG) 48 | 49 | ### Help mode 50 | ![Image Screenshot - C syntax highlighjt](https://github.com/DosWorld/dwed/raw/main/DWED-HLP.PNG) 51 | 52 | ### ASCII Table addon 53 | ![Image ASCII Table addon](https://github.com/DosWorld/dwed/raw/main/DWED-ASC.PNG) 54 | 55 | Inspired by 56 | 57 | ASCII program. Version 4.23 (C) Compact Soft, 1991. 58 | By: Alexander Dudarenko & Dmitry Kohmanyuk. 59 | 60 | Published at Softpanorama in 1993 (SP53A), now here is my remake for dwed. 61 | ### Calculator addon 62 | ![Image Calculator addon](https://github.com/DosWorld/dwed/raw/main/DWED-CLC.PNG) 63 | 64 | # Build and dependency 65 | 66 | Requires system2 library - https://github.com/DosWorld/libsystem2 67 | 68 | To build binaries, you need Turbo Pascal 6.0/7.0 in path, SPHINX C-- by Michael Sheker and my small make. Then - type 69 | 70 | make 71 | 72 | # License 73 | 74 | MIT License. See LICENSE file. 75 | -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/PRINT.H--: -------------------------------------------------------------------------------- 1 | /* 2 | (c) 2019 Copyright by Viacheslav Komenda 3 | 4 | This is free and unencumbered software released into the public domain. 5 | Anyone is free to copy, modify, publish, use, compile, sell, or 6 | distribute this software, either in source code form or as a compiled 7 | binary, for any purpose, commercial or non-commercial, and by any 8 | means. 9 | 10 | In jurisdictions that recognize copyright laws, the author or authors 11 | of this software dedicate any and all copyright interest in the 12 | software to the public domain. We make this dedication for the benefit 13 | of the public at large and to the detriment of our heirs and 14 | successors. We intend this dedication to be an overt act of 15 | relinquishment in perpetuity of all present and future rights to this 16 | software under copyright law. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | For more information, please refer to 27 | 28 | */ 29 | 30 | #ifndef _PRINT_H_ 31 | #define _PRINT_H_ 32 | 33 | // PRINT(char) 34 | inline void PRINT() { $PUSH AX, BX, CX, DX; DL = AL; AH = 0x02; $ INT 0x21; $POP DX, CX, BX, AX; } 35 | 36 | // PRINTLN() 37 | inline void PRINTLN() { $PUSH AX, BX, CX, DX; DL = 0x0d; AH = 0x02; $ INT 0x21; DL = 0x0a; AH = 0x02; $ INT 0x21; $POP DX, CX, BX, AX; } 38 | 39 | // PRINT_STR() 40 | inline void PRINT_STR() { $PUSH SI; SI = AX; $CLD; WHILE(TRUE) { $LODSB; IF(AL == 0) BREAK; PRINT(); } $POP SI; } 41 | 42 | // AL = byte 43 | inline void PRINT_HEX_BYTE() { AH = AL; AX &= 0xF00F; $PUSH AX; AL = AH; AL = AL >> 4; IF(AL > 9) PRINT(AL + 'A' - 10); ELSE PRINT(AL + '0'); $POP AX; IF(AL > 9) PRINT(AL + 'A' - 10); ELSE PRINT(AL + '0'); } 44 | 45 | // AW = word 46 | inline void PRINT_HEX_WORD() { $PUSH AX; AL=AH; PRINT_HEX_BYTE(); $POP AX; PRINT_HEX_BYTE(); } 47 | 48 | // AX = int 49 | :void PRINT_INT() { 50 | IF(int AX<0) { $NEG AX; $PUSH AX; PRINT('-'); $POP AX;} 51 | DX=0; BX = 10; $DIV BX; 52 | IF(AX !=0) { $PUSH DX; PRINT_INT(); $POP AX;} ELSE AX = DX; 53 | PRINT(AL + '0'); 54 | } 55 | // AX = uint 56 | :void PRINT_UINT() { 57 | DX=0; BX = 10; $DIV BX; 58 | IF(AX !=0) { $PUSH DX; PRINT_UINT(); $POP AX;} ELSE AX = DX; 59 | PRINT(AL + '0'); 60 | } 61 | 62 | :void printdword(dword i) 63 | dword j; 64 | { 65 | IF(i < 0) { i = -i; @PRINT('-'); } 66 | j = i / 10; 67 | IF (j != 0) printint(j); 68 | PRINT(i % 10 + '0'); 69 | } 70 | 71 | inline void HEX2CHAR() { IF( AL < 0x0A) { AL += '0'; } ELSE { AL -= 10; AL += 'A'; } } 72 | 73 | :word printhexbyte(word buf; byte b) { 74 | b = b & 0xff; 75 | AL = b; 76 | AH = AL; 77 | AL = AL >> 4; 78 | 79 | AL = AL & 0x0F; 80 | HEX2CHAR(); 81 | BX = buf; 82 | DSBYTE[BX] = AL; 83 | BX++; 84 | 85 | AL = AH; AL = AL & 0x0F; 86 | HEX2CHAR(); 87 | DSBYTE[BX] = AL; 88 | BX++; 89 | DSBYTE[BX] = 0; 90 | return (BX); 91 | } 92 | 93 | :word printhexword(word buf; word w) 94 | byte b; 95 | { 96 | b = w >> 8; 97 | buf = printhexbyte(buf, b); 98 | b = w & 0xFF; 99 | buf = printhexbyte(buf, b); 100 | return buf; 101 | } 102 | 103 | :word printhexdword(word buf; dword b) { 104 | buf = printhexword(buf, b >> 16); 105 | buf = printhexword(buf, b & 0xFFFF); 106 | return buf; 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /SRC/STRUTIL.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2020 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$F-,R-} 23 | unit strutil; 24 | 25 | interface 26 | 27 | function hexb(b : byte):string; 28 | function hexw(w : word):string; 29 | function hexdw(dw : longint):string; 30 | function hexp(p : pchar):string; 31 | 32 | function binb(b : byte):string; 33 | function bindw(l : longint):string; 34 | 35 | function octb(b : byte):string; 36 | 37 | function unquote(str : string) : string; 38 | 39 | procedure remove_tabs(var s : string; var tabs : string); 40 | 41 | implementation 42 | 43 | uses str; 44 | 45 | function hexb(b : byte):string; 46 | const a : string[16] = '0123456789ABCDEF'; 47 | begin 48 | hexb := a[((b shr 4) and $0f) + 1] + a[(b and $0f) + 1]; 49 | end; 50 | 51 | function hexw(w : word):string; 52 | begin 53 | hexw := hexb(hi(w)) + hexb(lo(w)); 54 | end; 55 | 56 | function hexdw(dw : longint):string; 57 | begin 58 | hexdw := hexw((dw shr 16) and $ffff) + hexw(dw and $ffff); 59 | end; 60 | 61 | function hexp(p : pchar):string; 62 | begin 63 | hexp := hexw(seg(p[0])) + ':' + hexw(ofs(p[0])); 64 | end; 65 | 66 | function binb(b : byte):string; 67 | var s : string[8]; 68 | i : integer; 69 | begin 70 | s[0] := #8; 71 | for i := 7 downto 0 do if (b and (1 shl i)) <> 0 then s[8-i] := '1' else s[8-i] := '0'; 72 | binb := s; 73 | end; 74 | 75 | function bindw(l : longint):string; 76 | begin 77 | bindw := concat(binb(l shr 24), binb(l shr 16), binb(l shr 8), binb(l)); 78 | end; 79 | 80 | function octb(b : byte):string; 81 | var s : string[4]; 82 | begin 83 | s := ' '; 84 | s[3] := chr($30 + (b and 7)); 85 | b := b shr 3; 86 | s[2] := chr($30 + (b and 7)); 87 | b := b shr 3; 88 | s[1] := chr($30 + (b and 3)); 89 | octb := s; 90 | end; 91 | 92 | function unquote(str : string) : string; 93 | begin 94 | if length(str) > 0 then begin 95 | if (str[1] = '"') and (str[length(str)] = '"') then begin 96 | str := copy(str, 2, length(str) - 2); 97 | end; 98 | end; 99 | unquote := str; 100 | end; 101 | 102 | procedure remove_tabs(var s : string; var tabs : string); 103 | var i : integer; 104 | r : string; 105 | begin 106 | if poschr(s, #9) = -1 then exit; 107 | i := 1; 108 | r := ''; 109 | while (i <= ord(s[0])) and (ord(r[0]) < 255) do begin 110 | if s[i] = #9 then begin 111 | r := r + tabs; 112 | end else begin 113 | r[ord(r[0]) + 1] := s[i]; 114 | inc(r[0]); 115 | end; 116 | inc(i); 117 | end; 118 | s := r; 119 | end; 120 | 121 | end. 122 | -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/OBJOMF.C--: -------------------------------------------------------------------------------- 1 | /* 2 | (c) 2019 Copyright by Viacheslav Komenda 3 | 4 | This is free and unencumbered software released into the public domain. 5 | 6 | Anyone is free to copy, modify, publish, use, compile, sell, or 7 | distribute this software, either in source code form or as a compiled 8 | binary, for any purpose, commercial or non-commercial, and by any 9 | means. 10 | 11 | In jurisdictions that recognize copyright laws, the author or authors 12 | of this software dedicate any and all copyright interest in the 13 | software to the public domain. We make this dedication for the benefit 14 | of the public at large and to the detriment of our heirs and 15 | successors. We intend this dedication to be an overt act of 16 | relinquishment in perpetuity of all present and future rights to this 17 | software under copyright law. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | For more information, please refer to 28 | 29 | */ 30 | 31 | #ifndef _OBJOMF_C_ 32 | #define _OBJOMF_C_ 33 | 34 | #include "objomf.h--" 35 | char __b[3]; 36 | 37 | char ORREAD(CX, SI, DI) { 38 | // f = CX, *recType = SI, *recLen = DI 39 | $PUSH SI,DI; 40 | read(CX, #__b, 3); 41 | $POP DI,SI; 42 | IF(AX == 3) { 43 | DSBYTE[SI] = __b[0]; 44 | AL = __b[1]; 45 | AH = __b[2]; 46 | DSWORD[DI] = AX; 47 | return TRUE; 48 | } 49 | return FALSE; 50 | } 51 | 52 | char ORWRITE(BX, CL, AX) { 53 | __b[0] = CL; 54 | __b[1] = AL; 55 | __b[2] = AH; 56 | 57 | IF(write(BX, #__b, 3) == 3) { 58 | AL = TRUE; 59 | } 60 | ELSE { 61 | AL = FALSE; 62 | } 63 | } 64 | 65 | word ormname(word dst, word fname) { 66 | word f; 67 | byte recType; 68 | word recLen, len; 69 | 70 | len = 0; 71 | f = open(fname, F_READ); 72 | IF(AX != 0) { 73 | IF(ORREAD(f, #recType, #recLen)) { 74 | IF(recType == THEADR) { 75 | read(f, #len, 1); 76 | read(f, dst, len); 77 | DSBYTE[dst + len] = 0; 78 | } 79 | } 80 | close(f); 81 | } 82 | return len; 83 | } 84 | 85 | word OADDB(AX, CL) { 86 | DSBYTE[AX] = CL; 87 | return AX + 1; 88 | } 89 | 90 | word OADDW(AX, CX) { 91 | DSWORD[AX] = CX; 92 | return AX + 2; 93 | } 94 | 95 | word OADDS(DI, SI) { 96 | BX = DI; 97 | CX = 0; 98 | DI++; 99 | WHILE(TRUE) { 100 | AL = DSBYTE[SI]; 101 | IF(AL == 0) BREAK; 102 | DSBYTE[DI] = AL; 103 | SI++; 104 | DI++; 105 | CX++; 106 | } 107 | DSBYTE[BX] = CL; 108 | return DI; 109 | } 110 | 111 | word ogets(word buf, word str) { 112 | DX = 0; 113 | SI = buf; 114 | DI = str; 115 | DL = DSBYTE[SI]; 116 | SI++; 117 | WHILE(DX != 0) { 118 | AL = DSBYTE[SI]; 119 | DSBYTE[DI] = AL; 120 | SI++; 121 | DI++; 122 | DX--; 123 | } 124 | DSBYTE[DI] = DL; 125 | return SI; 126 | } 127 | 128 | void OSKIP(BX, CX) { 129 | word pos[2]; 130 | 131 | SSWORD[#pos] = CX; 132 | SSWORD[#pos + 2] = 0; 133 | BSEEK(BX, #pos, SEEK_CUR); 134 | } 135 | 136 | char owmalign(word f) { 137 | word pos[2], newpos; 138 | char buf[16]; 139 | 140 | BTELL(f, #pos); 141 | newpos = pos[0] & 0x0F; 142 | IF(newpos != 0) { 143 | newpos = 0x10 - newpos; 144 | BX = 0; 145 | WHILE(BX != newpos) { 146 | buf[BX] = 0; 147 | BX++; 148 | } 149 | write(f, #buf, newpos); 150 | IF(AX != newpos) RETURN FALSE; 151 | } 152 | return TRUE; 153 | } 154 | 155 | void ormalign(word f) { 156 | word pos[2]; 157 | word newpos; 158 | 159 | BTELL(f, #pos); 160 | newpos = pos[0] & 0x0F; 161 | if(newpos != 0) { 162 | OSKIP(f, 0x10 - newpos); 163 | } 164 | } 165 | 166 | #endif 167 | -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/FILE.H--: -------------------------------------------------------------------------------- 1 | /* 2 | SPHINX Programming (C) 1994. 3 | NAME: FILE.H-- 4 | DESCRIPTION: File related constant definitions and procedures. 5 | LAST MODIFIED: 18 Dec 1994 6 | PROCEDURES DEFINED IN THIS FILE: 7 | : word appendfile(filename,bufsegment,bufoffset,bytes) 8 | : word close(filehandle) 9 | : word create(filename,attribute) 10 | : word open(filename,byte mode) 11 | : word read(filehandle,bufferoffset,bytes) 12 | : word readfar(filehandle,bufferseg,bufferoffset,bytes) 13 | : word readfile(filename,bufseg,bufoff,bytes) 14 | : word write(filehandle,bufferoffset,bytes) 15 | : word writefar(filehandle,bufferseg,bufferoffset,bytes) 16 | : word writefile(filename,bufseg,bufoff,bytes) 17 | */ 18 | 19 | 20 | /*** file access constansts for use with open() and FOPEN() ***/ 21 | 22 | enum { F_READ, F_WRITE, F_READWRITE }; 23 | 24 | 25 | /*** file attribute constants for use with create() and FCREATE() ***/ 26 | 27 | ?define FA_NORMAL 0x00 28 | ?define FA_READONLY 0x01 29 | ?define FA_HIDDEN 0x02 30 | ?define FA_SYSTEM 0x04 31 | ?define FA_VOLUME 0x08 32 | ?define FA_DIRECTORY 0x10 33 | ?define FA_ARCHIVE 0x20 34 | 35 | 36 | /*** standard input, output, error, auxilary and printer file handles ***/ 37 | 38 | ?define STDIN 0 39 | ?define STDOUT 1 40 | ?define STDERR 2 41 | ?define STDAUX 3 42 | ?define STDPRN 4 43 | 44 | 45 | /****** procedure definitions ******/ 46 | 47 | 48 | : word open (word filename; byte mode) 49 | { 50 | ?DOSrequired 0x200 51 | AL = mode; 52 | DX = filename; 53 | AH = 0x3D; 54 | $INT 0x21 55 | IF( CARRYFLAG ) 56 | AX = 0; 57 | } 58 | 59 | 60 | : word create (word filename, attribute) 61 | { 62 | ?DOSrequired 0x200 63 | CX = attribute; 64 | DX = filename; 65 | AH = 0x3C; 66 | $INT 0x21 67 | IF( CARRYFLAG ) 68 | AX = 0; 69 | } 70 | 71 | 72 | : word close (word filehandle) 73 | { 74 | ?DOSrequired 0x200 75 | BX = filehandle; 76 | AH = 0x3E; 77 | $INT 0x21 78 | IF( NOTCARRYFLAG ) 79 | AX = 0; 80 | } 81 | 82 | 83 | : word readfile (word filename,bufseg,bufoff,bytes) 84 | inline 85 | {?DOSrequired 0x0200 86 | $ DB 0x55,0x89,0xE5,0x36,0x8B,0x56,0xA,0xB8,0x0,0x3D, 87 | 0xCD,0x21,0x73,0x6,0x31,0xC0,0x5D,0xC2,0x8,0x0, 88 | 0x89,0xC3,0x36,0x8B,0x46,0x8,0x1E,0x8E,0xD8,0x36, 89 | 0x8B,0x56,0x6,0x36,0x8B,0x4E,0x4,0xB4,0x3F,0xCD, 90 | 0x21,0x73,0x2,0x31,0xC0,0x89,0xC2,0xB4,0x3E,0xCD, 91 | 0x21,0x89,0xD0,0x1F,0x5D,0xC2,0x8,0x0 92 | } 93 | 94 | 95 | : word appendfile (word filename,bufsegment,bufoffset,bytes) 96 | inline 97 | {?DOSrequired 0x0200 98 | $ DB 0x55,0x8B,0xEC,0x36,0x8B,0x56,0xA,0xB8,0x1,0x3D, 99 | 0xCD,0x21,0x73,0xE,0xB4,0x3C,0x33,0xC9,0xCD,0x21, 100 | 0x73,0x6,0x33,0xC0,0x5D,0xC2,0x8,0x0,0x89,0xC3, 101 | 0xB8,0x2,0x42,0x33,0xC9,0x33,0xD2,0xCD,0x21,0x72, 102 | 0x15,0x36,0x8B,0x46,0x8,0x1E,0x8E,0xD8,0x36,0x8B, 103 | 0x56,0x6,0x36,0x8B,0x4E,0x4,0xB4,0x40,0xCD,0x21, 104 | 0x73,0x2,0x33,0xC0,0x8B,0xD0,0xB4,0x3E,0xCD,0x21, 105 | 0x89,0xD0,0x1F,0x5D,0xC2,0x8,0x0 106 | } 107 | 108 | 109 | : word writefile (word filename,bufseg,bufoff,bytes) 110 | inline 111 | {?DOSrequired 0x0200 112 | $ DB 0x55,0x89,0xE5,0x36,0x8B,0x56,0xA,0xB4,0x3C,0x31, 113 | 0xC9,0xCD,0x21,0x73,0x6,0x31,0xC0,0x5D,0xC2,0x8, 114 | 0x0,0x89,0xC3,0x36,0x8B,0x46,0x8,0x1E,0x8E,0xD8, 115 | 0x36,0x8B,0x56,0x6,0x36,0x8B,0x4E,0x4,0xB4,0x40, 116 | 0xCD,0x21,0x73,0x2,0x31,0xC0,0x89,0xC2,0xB4,0x3E, 117 | 0xCD,0x21,0x89,0xD0,0x1F,0x5D,0xC2,0x8,0x0 118 | } 119 | 120 | 121 | : word read (word filehandle,bufferoffset,bytes) 122 | inline 123 | {?DOSrequired 0x0200 124 | $ DB 0x5F,0x59,0x5A,0x5B,0xB4,0x3F,0xCD,0x21,0x73,0x2, 125 | 0x31,0xC0,0xFF,0xE7 126 | } 127 | 128 | 129 | : word readfar (word filehandle,bufferseg,bufferoffset,bytes) 130 | inline 131 | {?DOSrequired 0x0200 132 | $ DB 0x5F,0x59,0x5A,0x8C,0xDE,0x1F,0x5B,0xB4,0x3F,0xCD, 133 | 0x21,0x73,0x2,0x31,0xC0,0x8E,0xDE,0xFF,0xE7 134 | } 135 | 136 | 137 | : word write (word filehandle,bufferoffset,bytes) 138 | inline 139 | {?DOSrequired 0x0200 140 | $DB 0x5F,0x59,0x5A,0x5B,0xB4,0x40,0xCD,0x21,0x73,0x2, 141 | 0x31,0xC0,0xFF,0xE7 142 | } 143 | 144 | 145 | : word writefar (word filehandle,bufferseg,bufferoffset,bytes) 146 | inline 147 | {?DOSrequired 0x0200 148 | $DB 0x5F,0x59,0x5A,0x8C,0xDE,0x1F,0x5B,0xB4,0x40,0xCD, 149 | 0x21,0x73,0x2,0x31,0xC0,0x8E,0xDE,0xFF,0xE7 150 | } 151 | 152 | 153 | /* end of FILE.H-- */ -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/STR.H--: -------------------------------------------------------------------------------- 1 | /* 2 | (c) 2019 Copyright by Viacheslav Komenda 3 | 4 | This is free and unencumbered software released into the public domain. 5 | Anyone is free to copy, modify, publish, use, compile, sell, or 6 | distribute this software, either in source code form or as a compiled 7 | binary, for any purpose, commercial or non-commercial, and by any 8 | means. 9 | 10 | In jurisdictions that recognize copyright laws, the author or authors 11 | of this software dedicate any and all copyright interest in the 12 | software to the public domain. We make this dedication for the benefit 13 | of the public at large and to the detriment of our heirs and 14 | successors. We intend this dedication to be an overt act of 15 | relinquishment in perpetuity of all present and future rights to this 16 | software under copyright law. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | For more information, please refer to 27 | 28 | */ 29 | 30 | #ifndef _STR_H_ 31 | #define _STR_H_ 32 | 33 | void BASENAME(DI) { 34 | 35 | BX = DI; 36 | 37 | WHILE(1) { 38 | AL = DSBYTE[BX]; 39 | IF(AL == 0) BREAK; 40 | BX++; 41 | } 42 | 43 | WHILE(1) { 44 | AL = DSBYTE[BX]; 45 | IF(BX == DI) BREAK; 46 | IF(AL == ':') { 47 | BX++; 48 | BREAK; 49 | } 50 | IF(AL == '/') { 51 | BX++; 52 | BREAK; 53 | } 54 | IF(AL == '\\') { 55 | BX++; 56 | BREAK; 57 | } 58 | BX--; 59 | 60 | } 61 | 62 | WHILE(1) { 63 | AL = DSBYTE[BX]; 64 | DSBYTE[DI] = AL; 65 | IF(AL == 0) BREAK; 66 | BX++; 67 | DI++; 68 | } 69 | } 70 | 71 | inline char UCASE() { 72 | IF(AL>='a') IF(AL<='z') AL -=0x20; 73 | } 74 | 75 | inline char LCASE() { 76 | IF(AL>='A') IF(AL<='A') AL +=0x20; 77 | } 78 | 79 | // AX = addr 80 | : 81 | word STRLEN(BX) { 82 | $PUSH CX; 83 | CX = 0; 84 | WHILE(TRUE) { 85 | AL = DSBYTE[BX]; 86 | IF(AL == 0) BREAK; 87 | BX++; 88 | CX++; 89 | } 90 | AX = CX; 91 | $POP CX; 92 | } 93 | // AX = addr1, BX = addr2 94 | : 95 | char STRCMP(AX, BX) { 96 | $PUSH BX, DX, CX; 97 | DX = AX; 98 | CH = FALSE; 99 | WHILE(TRUE) { 100 | AL = DSBYTE[BX]; 101 | AH = DSBYTE[DX]; 102 | IF(AL != AH) { 103 | BREAK; 104 | } 105 | IF(AL == 0) { 106 | CH = TRUE; 107 | BREAK; 108 | } 109 | BX++; 110 | DX++; 111 | } 112 | AL = CH; 113 | $POP CX, DX, BX; 114 | } 115 | 116 | // AX = addr1, BX = addr2 117 | : 118 | char STRICMP(AX, BX) { 119 | $PUSH BX, DX, CX; 120 | DX = AX; 121 | CH = FALSE; 122 | WHILE(TRUE) { 123 | AH = @UCASE(DSBYTE[DX]); 124 | AL = @UCASE(DSBYTE[BX]); 125 | IF(AL != AH) { 126 | BREAK; 127 | } 128 | IF(AL == 0) { 129 | CH = TRUE; 130 | BREAK; 131 | } 132 | BX++; 133 | DX++; 134 | } 135 | AL = CH; 136 | $POP CX, DX, BX; 137 | } 138 | 139 | // BX = addr 140 | : 141 | word UPSTR(BX) { 142 | WHILE(TRUE) { 143 | AL = DSBYTE[BX]; 144 | IF(AL == 0) BREAK; 145 | @UCASE(); 146 | DSBYTE[BX] = AL; 147 | BX++; 148 | } 149 | } 150 | 151 | // AX = addr 152 | : 153 | word LOSTR(BX) { 154 | WHILE(TRUE) { 155 | AL = DSBYTE[BX]; 156 | IF(AL == 0) BREAK; 157 | @LCASE(); 158 | DSBYTE[BX] = AL; 159 | BX++; 160 | } 161 | } 162 | 163 | // AX = dest, BX = src 164 | : 165 | word STRCPY(AX, BX) { 166 | $PUSH SI,DI; 167 | $CLD; 168 | SI = BX; 169 | DI = AX; 170 | WHILE(TRUE) { 171 | $LODSB; 172 | $STOSB; 173 | IF(AL==0) BREAK; 174 | } 175 | AX = DI; 176 | $POP DI, SI; 177 | } 178 | // AX = dest, BX = src; 179 | : 180 | word STRCAT (AX, BX) { 181 | $PUSH DI, SI; 182 | SI = BX; 183 | DI = AX; 184 | $CLD; 185 | WHILE(ESBYTE[DI] != 0) { 186 | DI++; 187 | } 188 | WHILE(TRUE) { 189 | $LODSB; 190 | $STOSB; 191 | IF(AL == 0) BREAK; 192 | } 193 | AX = DI; 194 | $POP SI, DI; 195 | } 196 | 197 | void strup(word str) { 198 | @UPSTR(str); 199 | } 200 | 201 | #endif 202 | -------------------------------------------------------------------------------- /SRC/EVENT.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2020 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | unit event; 23 | 24 | interface 25 | 26 | const 27 | key_ctrl = 1; 28 | key_shift = 2; 29 | key_alt = 4; 30 | 31 | type 32 | EventType = (NONE, 33 | KEYBOARD, 34 | MOUSE_MOVE, 35 | MOUSE_PRESS_B1, MOUSE_PRESS_B2, 36 | MOUSE_RELEASE_B1, MOUSE_RELEASE_B2 37 | ); 38 | 39 | PEvent = ^TEvent; 40 | TEvent = record 41 | etype : EventType; 42 | scancode : byte; 43 | ascii : char; 44 | ctrl_keys : word; 45 | mouse_left : boolean; 46 | mouse_right : boolean; 47 | mouse_x : integer; 48 | mouse_y : integer; 49 | end; 50 | 51 | procedure wait_event(var e : TEvent); 52 | function has_event : boolean; 53 | function ctrl_key_word(is_ctrl, is_shift, is_alt : boolean) : word; 54 | 55 | implementation 56 | 57 | uses kminput; 58 | 59 | function has_event:boolean; 60 | begin 61 | has_event := kbd_haskey; 62 | end; 63 | 64 | procedure wait_event(var e : TEvent); 65 | var state : byte; 66 | newstate : byte; 67 | mx, my : integer; 68 | flags : byte; 69 | key : word; 70 | begin 71 | fillchar(e, sizeof(TEvent), #0); 72 | e.etype := NONE; 73 | if mouse_avail then begin 74 | state := mouse_buttons; 75 | e.mouse_x := mouse_getx; 76 | mx := mouse_getx; 77 | my := mouse_gety; 78 | e.mouse_y := mouse_gety; 79 | end else begin 80 | e.mouse_x := 0; 81 | e.mouse_y := 0; 82 | e.mouse_left := false; 83 | e.mouse_right := false; 84 | end; 85 | while e.etype = NONE do begin 86 | if kbd_haskey then begin 87 | key := kbd_getkey; 88 | e.etype := KEYBOARD; 89 | e.scancode := hi(key); 90 | e.ascii := chr(lo(key)); 91 | end else if mouse_avail then begin 92 | newstate := mouse_buttons; 93 | e.mouse_x := mouse_getx; 94 | e.mouse_y := mouse_gety; 95 | e.mouse_left := (newstate and MOUSE_B1) <> 0; 96 | e.mouse_right := (newstate and MOUSE_B2) <> 0; 97 | if state <> newstate then begin 98 | if (newstate and MOUSE_B1) <> (state and MOUSE_B1) then begin 99 | if (newstate and MOUSE_B1) <> 0 then 100 | e.etype := MOUSE_PRESS_B1 101 | else e.etype := MOUSE_RELEASE_B1; 102 | end else if (newstate and MOUSE_B2) <> (state and MOUSE_B2) then begin 103 | if (newstate and MOUSE_B2) <> 0 then 104 | e.etype := MOUSE_PRESS_B2 105 | else e.etype := MOUSE_RELEASE_B2; 106 | end; 107 | end else if (e.mouse_x <> mx) or (e.mouse_y <> my) then begin 108 | e.etype := MOUSE_MOVE; 109 | end; 110 | end; 111 | if e.etype = NONE then begin 112 | asm 113 | mov ax,$8600 114 | xor cx, cx 115 | mov dx, 250 116 | int $15 117 | end; 118 | end; 119 | end; 120 | if e.etype <> MOUSE_MOVE then begin 121 | flags := kbd_getflags; 122 | e.ctrl_keys := ctrl_key_word(is_ctrl(flags), is_shift(flags), is_alt(flags)); 123 | end; 124 | end; 125 | 126 | function ctrl_key_word(is_ctrl, is_shift, is_alt : boolean) : word; 127 | var r : word; 128 | begin 129 | r := 0; 130 | if is_ctrl then r := r or key_ctrl; 131 | if is_shift then r := r or key_shift; 132 | if is_alt then r := r or key_alt; 133 | ctrl_key_word := r; 134 | end; 135 | 136 | end. 137 | -------------------------------------------------------------------------------- /SRC/DWEDTYPE.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2020 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$A-} 23 | unit dwedtype; 24 | 25 | interface 26 | 27 | uses strs, dwedhl, event; 28 | 29 | const 30 | SCRU_QUIT = 1; 31 | SCRU_NONE = 2; 32 | SCRU_TOP = 3; 33 | SCRU_CLINE = 4; 34 | SCRU_SD = 5; 35 | SCRU_SU = 6; 36 | SCRU_FULL = 7; 37 | 38 | CB_SIZE = 1024 * 32; 39 | PROGRESS_UPDATE = 1024 * 4; 40 | 41 | MEM_DOS = 'DOS'; 42 | MEM_SWAP = 'SWAP'; 43 | MEM_SXMS = 'SXMS'; 44 | 45 | ENV_TEMP = 'TEMP'; 46 | ENV_TMP = 'TMP'; 47 | 48 | OVERLAY_MSG = 'This is overlay. Run DWED.EXE'; 49 | WELCOME_MSG = 'Welcome! Press ~F1~ for help'; 50 | DEFAULT_FILE_NAME = 'NONAME.TXT'; 51 | 52 | CONFIG_FILE_NAME = 'DWED.CFG'; 53 | 54 | CFG_TAB_SIZE = 'TAB_SIZE'; 55 | CFG_COLOR_TOP = 'COLOR.TOP'; 56 | CFG_COLOR_TOP_HL = 'COLOR.TOP_HL'; 57 | CFG_COLOR_TEXT = 'COLOR.TEXT'; 58 | CFG_COLOR_TEXT_HL = 'COLOR.TEXT_HL'; 59 | CFG_COLOR_TEXT_DL = 'COLOR.TEXT_DL'; 60 | CFG_COLOR_TEXT_SEL = 'COLOR.TEXT_SEL'; 61 | CFG_COLOR_MENU = 'COLOR.MENU'; 62 | CFG_COLOR_MENU_SEL = 'COLOR.MENU_SEL'; 63 | CFG_COLOR_HELP_MENU = 'COLOR.HELP_MENU'; 64 | CFG_COLOR_HELP_MENU_SEL = 'COLOR.HELP_MENU_SEL'; 65 | CFG_COLOR_HELP = 'COLOR.HELP'; 66 | CFG_COLOR_HELP_HL = 'COLOR.HELP_HL'; 67 | CFG_USR_DEF_F5 = 'USR.DEF.F5'; 68 | CFG_USR_DEF_F8 = 'USR.DEF.F8'; 69 | CFG_USR_DEF_F9 = 'USR.DEF.F9'; 70 | CFG_HL_ENABLE = 'HL.ENABLE'; 71 | CFG_MEMORY = 'MEMORY'; 72 | 73 | type 74 | PString = ^String; 75 | PWord = ^Word; 76 | PLongint = ^Longint; 77 | DWord = Longint; 78 | 79 | PColorConfig =^ TColorConfig; 80 | TColorConfig = record 81 | top : byte; 82 | top_hl : byte; 83 | text : byte; 84 | text_hl : byte; 85 | text_dl : byte; 86 | text_sel : byte; 87 | menu : byte; 88 | menu_sel : byte; 89 | help_menu : byte; 90 | help_menu_sel : byte; 91 | help : byte; 92 | help_hl : byte; 93 | end; 94 | 95 | PConfig =^ TConfig; 96 | TConfig = record 97 | width : integer; 98 | height : integer; 99 | color : TColorConfig; 100 | hl_enable : boolean; 101 | tab_size : integer; 102 | udef_f5 : string; 103 | udef_f8 : string; 104 | udef_f9 : string; 105 | memory : string; 106 | end; 107 | 108 | TLineEditorContext = record 109 | x : integer; 110 | line : string; 111 | chg : boolean; 112 | selection : boolean; 113 | sel_row : DWord; 114 | sel_x : integer; 115 | end; 116 | 117 | PFileContext =^ TFileContext; 118 | TFileContext = record 119 | fname : string; 120 | sfname : string; 121 | st : SourceType; 122 | chg : boolean; 123 | total : DWord; 124 | scrx, scry : integer; 125 | next : PFileContext; 126 | rline : EditorStr; 127 | cline : EditorStr; 128 | scrline : EditorStr; 129 | editor : TLineEditorContext; 130 | config : PConfig; 131 | end; 132 | 133 | PEditorContext =^ TEditorContext; 134 | TEditorContext = record 135 | ins : boolean; 136 | exit_code : byte; 137 | current : PFileContext; 138 | all : PFileContext; 139 | clipboard : pchar; 140 | has_wincb : boolean; 141 | search : string[64]; 142 | searchCaseSens : boolean; 143 | replace : string[64]; 144 | config : TConfig; 145 | help_topic_id : integer; 146 | temp : string; 147 | end; 148 | 149 | {$F+} 150 | TEventProc = function(var ctx : TEditorContext; e : PEvent) : integer; 151 | TPercentUpdateProc = procedure(value, total, start_date : DWord); 152 | {$F-} 153 | 154 | PEventHandler =^ TEventHandler; 155 | TEventHandler = record 156 | event : TEvent; 157 | reset_selection : boolean; 158 | proc : pointer; 159 | next : PEventHandler; 160 | end; 161 | 162 | implementation 163 | 164 | end. 165 | -------------------------------------------------------------------------------- /TOOLS/BIN2OBJ/BIN2OBJ.C--: -------------------------------------------------------------------------------- 1 | /* 2 | (c) 2019 Copyright by Viacheslav Komenda 3 | 4 | This is free and unencumbered software released into the public domain. 5 | Anyone is free to copy, modify, publish, use, compile, sell, or 6 | distribute this software, either in source code form or as a compiled 7 | binary, for any purpose, commercial or non-commercial, and by any 8 | means. 9 | 10 | In jurisdictions that recognize copyright laws, the author or authors 11 | of this software dedicate any and all copyright interest in the 12 | software to the public domain. We make this dedication for the benefit 13 | of the public at large and to the detriment of our heirs and 14 | successors. We intend this dedication to be an overt act of 15 | relinquishment in perpetuity of all present and future rights to this 16 | software under copyright law. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | For more information, please refer to 27 | 28 | */ 29 | 30 | ?use8086 31 | ?parsecommandline TRUE 32 | ?resize FALSE 33 | 34 | #include "stdlib.h--" 35 | #include "print.h--" 36 | #include "str.h--" 37 | #include "file.h--" 38 | #include "objomf.c--" 39 | 40 | #define IOBUF_SIZE 1024 41 | 42 | char iobuf[IOBUF_SIZE]; 43 | 44 | char buf[256]; 45 | char name2[256]; 46 | word pEnd[2], pBegin[2]; 47 | word count, ofs; 48 | 49 | void ERROR(BX,CX) { 50 | $PUSH CX; 51 | PRINT_STR(BX); 52 | $POP CX; 53 | PRINT_STR(CX); 54 | PRINTLN(); 55 | } 56 | 57 | int run(word iname, word oname, word pubname) { 58 | word i, o, ptr; 59 | 60 | i = open(iname, F_READ); 61 | if(AX == 0) { 62 | ERROR("ERROR:Could not read ", oname); 63 | return 1; 64 | } 65 | DSWORD[#pBegin + 2] = DSWORD[#pBegin] = 0; 66 | 67 | BSEEK(i, #pBegin, SEEK_END); 68 | BTELL(i, #pEnd); 69 | BSEEK(i, #pBegin, SEEK_SET); 70 | 71 | if(DSWORD[#pEnd + 2] != 0) { 72 | PRINT_STR("ERROR:Input file greater then 64K\n"); 73 | close(i); 74 | return 1; 75 | } 76 | 77 | o = open(oname, F_WRITE); 78 | if(AX == 0) { 79 | o = create(oname, FA_NORMAL); 80 | if(AX == 0) { 81 | ERROR("ERROR:Could not write ", oname); 82 | close(i); 83 | return 1; 84 | } 85 | } 86 | 87 | strcpy(#name2, oname); 88 | BASENAME(#name2); 89 | strup(#name2); 90 | 91 | /* 92 | Module header 93 | */ 94 | ptr = OADDS(#buf, #name2); 95 | ptr = OADDB(ptr, 0); 96 | ORWRITE(o, THEADR, ptr - #buf); 97 | write(o, #buf, ptr - #buf); 98 | 99 | /* 100 | Comment 101 | */ 102 | OADDB(#buf, 0); 103 | OADDS(AX, "BIN2OBJ (c) DosWorld 2019"); 104 | OADDS(AX, "Public domain (The Unlicense http://unlicense.org)"); 105 | ptr = OADDB(AX, 0) - #buf; 106 | ORWRITE(o, COMENT, ptr); 107 | write(o, #buf, ptr); 108 | 109 | OADDS(#buf, ""); 110 | OADDS(AX, "DGROUP"); 111 | OADDS(AX, "_TEXT"); 112 | OADDS(AX, "TEXT"); 113 | ptr = OADDB(AX, 0) - #buf; 114 | ORWRITE(o, LNAMES, ptr); 115 | write(o, #buf, ptr); 116 | 117 | /* 118 | Write SEGDEF16 for DATA 119 | */ 120 | OADDB(#buf, SEGA_BYTE | SEGC_PUBLIC | SEGS_NOTBIG); 121 | OADDW(AX, DSWORD[#pEnd]); 122 | OADDB(AX, 0x03); /* name */ 123 | OADDB(AX, 0x04); /* class */ 124 | OADDB(AX, 0x01); /* ??? */ 125 | ptr = OADDB(AX, 0) - #buf; 126 | ORWRITE(o, SEGDEF16, ptr); 127 | write(o, #buf, ptr); 128 | 129 | /* 130 | Include _DATA into DGROUP 131 | */ 132 | OADDB(#buf, 0x02); 133 | OADDB(AX, 0xff); 134 | OADDB(AX, 0x01); 135 | ptr = OADDB(AX, 0) - #buf; 136 | ORWRITE(o, GRPDEF, ptr); 137 | write(o, #buf, ptr); 138 | 139 | /* 140 | Write public name 141 | */ 142 | OADDB(#buf, 0); // reserved 143 | OADDB(AX, 1); // Segment Idx 144 | OADDS(AX, pubname); 145 | OADDW(AX, 0); // offset 146 | OADDB(AX, 0); // type 0, no debug info 147 | ptr = OADDB(AX, 0) - #buf; 148 | ORWRITE(o, PUBDEF16, ptr); 149 | write(o, #buf, ptr); 150 | 151 | /* 152 | Copy file content with 1024 blocks 153 | */ 154 | ofs = 0; 155 | while(DSWORD[#pEnd] != 0) { 156 | count = DSWORD[#pEnd]; 157 | IF(count > 1023) { 158 | count = 1023; 159 | } 160 | 161 | OADDB(#buf, 1); /* Segment No */ 162 | ptr = OADDW(AX, ofs) - #buf; /* Offset */ 163 | ORWRITE(o, LEDATA16, count + 4); 164 | write(o, #buf, ptr); 165 | 166 | read(i, #iobuf, count); 167 | write(o, #iobuf, count); 168 | iobuf[0] = 0; 169 | write(o, #iobuf, 1); 170 | DSWORD[#pEnd] -= count; 171 | ofs += count; 172 | } 173 | 174 | /* 175 | Module footer: non-main, no start 176 | */ 177 | OADDB(#buf, MA_NM_NS); 178 | ptr = OADDB(AX, 0) - #buf; 179 | ORWRITE(o, MODEND16, ptr); 180 | write(o, #buf, ptr); 181 | 182 | close(i); 183 | close(o); 184 | return 0; 185 | } 186 | 187 | void main() { 188 | if(@PARAMCOUNT() != 3) { 189 | PRINT_STR("BIN2OBJ (c) DosWorld 2019\nPublic domain (The Unlicense http://unlicense.org)\n\n"); 190 | PRINT_STR("Usage:\n\tbin2obj inputfile outputfile.obj publicname\n"); 191 | EXIT(1); 192 | } 193 | EXIT(run(PARAMSTR(0), PARAMSTR(1), PARAMSTR(2))); 194 | } 195 | -------------------------------------------------------------------------------- /SRC/DWEDHELP.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2020 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | unit dwedhelp; 23 | 24 | interface 25 | 26 | procedure dwed_help(var topic_id:integer; 27 | help_menu_clr, 28 | help_menu_sel_clr, 29 | help_clr, 30 | help_hl_clr : byte); 31 | 32 | implementation 33 | 34 | uses kminput, event, scr, scrui, str, help; 35 | 36 | procedure helpbin;external; 37 | {$L dwedhelp.obj} 38 | 39 | var topic_list : PHelpTopicList; 40 | topic_menu : pchar; 41 | width : integer; 42 | 43 | function get_name(t : PHelpTopicList):string; 44 | var s : string; 45 | i : integer; 46 | begin 47 | s := ''; 48 | for i := 1 to 12 do s := s + t^.topic.name[i]; 49 | get_name := trim(s); 50 | end; 51 | 52 | procedure dwed_help(var topic_id:integer; 53 | help_menu_clr, 54 | help_menu_sel_clr, 55 | help_clr, 56 | help_hl_clr : byte); 57 | 58 | var r : PHelpTopicList; 59 | y, i : integer; 60 | p : pchar; 61 | helpStr : string; 62 | selItem : integer; 63 | e : TEvent; 64 | begin 65 | scr.cursor_off; 66 | r := nil; 67 | selItem := topic_id; 68 | while true do begin 69 | r := topic_list; 70 | i := topic_id; 71 | while (i <> 0) and (r <> nil) do begin 72 | dec(i); 73 | r := r^.next; 74 | end; 75 | if r <> nil then begin 76 | for i := 1 to scr.getheight - 1 do scr.cln(width + 4, i, help_clr); 77 | scr.printhl(width + 5, 2, help_clr, help_hl_clr, '~' + #$9 + '~ Help topic - ~' + get_name(r) + '~'); 78 | p := r^.htext; 79 | i := r^.hlen; 80 | y := 4; 81 | helpStr := ''; 82 | while i <> 0 do begin 83 | case p[0] of 84 | #$0A: begin 85 | if (helpStr[1] <> '/') 86 | and (helpStr[2] <> '/') 87 | and (length(helpStr) > 0) then begin 88 | scr.printhl(width + 5, y, help_clr, help_hl_clr, helpStr); 89 | end; 90 | inc(y); 91 | helpStr := ''; 92 | end; 93 | #$0D: 94 | else helpStr := helpStr + p[0]; 95 | end; 96 | inc(p); 97 | dec(i); 98 | end; 99 | if (helpStr[1] <> '/') 100 | and (helpStr[2] <> '/') 101 | and (length(helpStr) > 0) then begin 102 | scr.printhl(width + 5, y, help_clr, help_hl_clr, helpStr); 103 | end; 104 | end; 105 | while true do begin 106 | scrui.vmenu(e, 0, 1, width + 4, scr.getheight - 1, 107 | help_menu_clr, help_menu_sel_clr, 108 | 'Help', topic_menu, selItem); 109 | if e.etype = KEYBOARD then break; 110 | end; 111 | case e.scancode of 112 | SCAN_ESC: break; 113 | SCAN_BS: break; 114 | SCAN_ENTER: topic_id := selItem; 115 | SCAN_SPACE: topic_id := selItem; 116 | end; 117 | end; 118 | kbd_reset; 119 | end; 120 | 121 | procedure init; 122 | var t : PHelpTopicList; 123 | len, maxlen : integer; 124 | totallen : integer; 125 | i, pos : integer; 126 | topicname : string; 127 | begin 128 | topic_list := from_memory(Pointer(@helpbin)); 129 | maxlen := 0; 130 | totallen := 0; 131 | t := topic_list; 132 | while t <> nil do begin 133 | topicname := get_name(t); 134 | len := t^.topic.lvl * 2 + length(topicname); 135 | if maxlen < len then maxlen := len; 136 | inc(totallen, len + 1); 137 | t := t^.next; 138 | end; 139 | getmem(topic_menu, totallen); 140 | pos := 0; 141 | t := topic_list; 142 | while t <> nil do begin 143 | topicname := get_name(t); 144 | if topicname = '$' then break; 145 | if pos <> 0 then begin 146 | topic_menu[pos] := #$0A; 147 | inc(pos); 148 | end; 149 | topicname := lpad(topicname, length(topicname) + t^.topic.lvl * 2); 150 | for i := 1 to length(topicname) do begin 151 | topic_menu[pos] := topicname[i]; 152 | inc(pos); 153 | end; 154 | t := t^.next; 155 | end; 156 | topic_menu[pos] := #0; 157 | width := maxlen; 158 | end; 159 | 160 | begin 161 | init; 162 | end. 163 | -------------------------------------------------------------------------------- /TOOLS/VGA3X/SRC/VGA3X.ASM: -------------------------------------------------------------------------------- 1 | ; 2 | ; VGA3x 3 | ; 4 | ; Here are two resident programs that allow forcibly set VGA adapters 5 | ; to 30-line mode when trying to install via BIOS 2nd or 3rd video mode. 6 | ; 7 | ; VGA3x - checks the video mode setting, and if the 2nd or 3rd one is set, 8 | ; then independently sets the 30(34) line mode using VGA ports. 9 | ; 10 | ; When writing this program, the source code of the program was used 11 | ; VGA480 by Dmitry Gurtyak. 12 | ; 13 | ; Ways of changing the source texts to change the inline modes are 14 | ; indicated in the comments. 15 | ; 16 | ; Published in Softpanorama 1993, Vol 4(38). SP54A 17 | ; 18 | ; Build: 19 | ; 20 | ; nasm -f bin vga3x.asm -DVGA30 -o vga30.com 21 | ; nasm -f bin vga3x.asm -DVGA34 -o vga34.com 22 | ; 23 | ; License 24 | ; 25 | ; Public domain 26 | ; 27 | ; I am (DosWorld) not author, just translate to english and Nasm. :) 28 | ; 29 | ; Added lines (to reduce tsr-size): 30 | ; 31 | ; mov es, word[PSP_ENV_SEG] 32 | ; mov ah, INT21_FREE_MEM 33 | ; int 21h 34 | ; 35 | ; Also, added few minor changes. 36 | ; 37 | ; Original author: 38 | ; 39 | ; Vadim V.Belman, 40 | ; Dniepropetrovsk, 41 | ; Work phone : (0562)448-158 42 | ; Network 2:464/20.4@fidonet 43 | ; 44 | 45 | PSP_ENV_SEG equ 2Ch 46 | 47 | INT21_FREE_MEM equ 49h 48 | INT21_GET_INT_VECT equ 35h 49 | INT21_SET_INT_VECT equ 25h 50 | 51 | INT27_TSR equ 27h 52 | 53 | section .code 54 | bits 16 55 | org 100h 56 | 57 | jmp main_part 58 | 59 | SeqData: 60 | dw 00100h 61 | dw 00001h 62 | dw 00302h 63 | dw 00003h 64 | dw 00204h 65 | dw 00300h 66 | 67 | dw 00c11h 68 | dw 00b06h 69 | dw 03e07h 70 | %ifdef VGA30 71 | ; 04f09h for 30 lines 72 | dw 04f09h 73 | %endif 74 | %ifdef VGA34 75 | ; 04d09h for 34 lines 76 | dw 04d09h 77 | %endif 78 | dw 0ea10h 79 | dw 08c11h 80 | %ifdef VGA30 81 | ; 0df12h for 30 lines 82 | dw 0df12h 83 | %endif 84 | %ifdef VGA34 85 | ; 0db12h for 34 lines 86 | dw 0db12h 87 | %endif 88 | dw 0e715h 89 | dw 00416h 90 | clear_scr: 91 | db 0 92 | int10h: 93 | pushf 94 | cmp ah, 0 95 | je analog_mode 96 | jmp end_res 97 | analog_mode: 98 | mov byte[cs: clear_scr],1 99 | cmp al, 3 100 | je set_30 101 | cmp al, 2 102 | jne without_cls 103 | jmp short set_30 104 | 105 | without_cls: 106 | cmp al, 82h 107 | je set_30_wc 108 | cmp al, 83h 109 | je set_30_wc 110 | jmp end_res 111 | set_30_wc: 112 | mov byte[cs: clear_scr],0 113 | set_30: 114 | push ax 115 | push bx 116 | push cx 117 | push dx 118 | push si 119 | push ds 120 | push es 121 | 122 | mov ax, cs 123 | mov ds, ax 124 | 125 | mov ax, 0003h 126 | pushf 127 | ; call dword[old_10] is replaced with 0ffh, 1eh 128 | db 0ffh, 1eh 129 | dw old_10 130 | %ifdef VGA30 131 | ; 1114h for 30 lines 132 | mov ax, 1114h 133 | %endif 134 | %ifdef VGA34 135 | ; 1111h for 34 lines 136 | mov ax, 1111h 137 | %endif 138 | 139 | mov bl, 0 140 | pushf 141 | ; call dword[old_10] is replaced with 0ffh, 1eh 142 | db 0ffh, 1eh 143 | dw old_10 144 | mov si, SeqData 145 | mov dx, 3c4h 146 | mov cx, 5 147 | cld 148 | lp1: 149 | lodsw 150 | out dx, ax 151 | ; loop sequencer write 152 | loop lp1 153 | mov dl, 0c2h 154 | ; code for 480 155 | mov al, 0e7h 156 | ; write misc register 157 | out dx, al 158 | ; sequencer adr. again 159 | mov dl, 0c4h 160 | lodsw 161 | out dx, ax 162 | ; 0b4h for mono 163 | mov dl, 0d4h 164 | mov cx, 9 165 | lp2: 166 | lodsw 167 | out dx, ax 168 | ; loop CRTC write 169 | loop lp2 170 | 171 | xor ax, ax 172 | mov es, ax 173 | %ifdef VGA30 174 | ; 29 for 30 lines 175 | mov byte[es: 484h],29 176 | %endif 177 | %ifdef VGA34 178 | ; 33 for 34 lines 179 | mov byte[es: 484h],33 180 | %endif 181 | ; for cursor emulate 182 | and byte[es: 487h],0feh 183 | ; set video mode 3 184 | mov byte[es: 449h],3 185 | %ifdef VGA30 186 | ; 12C0 for 30 lines 187 | mov word[es: 44Ch],12C0h 188 | %endif 189 | %ifdef VGA34 190 | ; 1540 for 34 lines 191 | mov word[es: 44Ch],1540h 192 | %endif 193 | mov bx,[es: 044eh] 194 | mov ax, 0b800h 195 | mov es, ax 196 | mov byte[es: bx],'#' 197 | 198 | cmp byte[cs: clear_scr],1 199 | jne end_set 200 | mov ax, 0600h 201 | xor cx, cx 202 | mov dx, 1D4Fh 203 | mov bh, 07h 204 | pushf 205 | ; call dword[old_10] is replaced with 0ffh, 1eh 206 | db 0ffh, 1eh 207 | dw old_10 208 | end_set: 209 | pop es 210 | pop ds 211 | pop si 212 | pop dx 213 | pop cx 214 | pop bx 215 | pop ax 216 | popf 217 | iret 218 | end_res: 219 | popf 220 | ; jmp far 221 | db 0eah 222 | old_10: 223 | offs: 224 | dw 0 225 | segm: 226 | dw 0 227 | ; ---------------------------------------------- 228 | tsr_end: 229 | msg: db 'VGA3x driver installed.', 0Dh, 0Ah, '$' 230 | main_part: 231 | push cs 232 | pop ds 233 | mov ah, INT21_GET_INT_VECT 234 | mov al, 10h 235 | int 21h 236 | mov word[segm],es 237 | mov word[offs],bx 238 | 239 | mov dx, int10h 240 | mov al, 10h 241 | mov ah, INT21_SET_INT_VECT 242 | int 21h 243 | 244 | mov ah, 0 245 | mov al, 3 246 | int 10h 247 | 248 | mov es, word[PSP_ENV_SEG] 249 | mov ah, INT21_FREE_MEM 250 | int 21h 251 | 252 | mov dx, msg 253 | mov ah, 9 254 | int 21h 255 | 256 | mov dx, tsr_end 257 | int INT27_TSR 258 | 259 | -------------------------------------------------------------------------------- /SRC/DWED.TXT: -------------------------------------------------------------------------------- 1 | ///1ABOUT 2 | About ~DWED~. 3 | 4 | ~DWED~ is a fullfeatured multifile text-editor with 5 | cliboard and syntax highlight support. 6 | 7 | You can use ~DWED~ as ~IDE~ for programming. 8 | 9 | Designed for ~IBM-XT~-grade PC with Intel ~8086~/~88~ CPU 10 | and works in Real Mode ~without~ DPMI, but support editing 11 | up to ~2G~ files. 12 | 13 | (c) ~DosWorld~ 2020 MIT License 14 | 15 | ~https://github.com/DosWorld/dwed/~ 16 | ///1INTERNALS 17 | Few tricks. 18 | 19 | 1. Some time, editor ask you something like 20 | 21 | ~Can i do %something%? (Y/N)~ 22 | 23 | In this case, you can press ~Y~ or ~ENTER~ - to answer ~YES~ 24 | and ~N~ or ~ESC~ - to answer ~NO~. 25 | 26 | 2. For micro-instalation need only two files: ~DWED.EXE~ and 27 | ~DWEDOVL.EXE~. 28 | 29 | 3. You can store ~DWED.CFG~ in local dir, also. 30 | 31 | 4. You can disable highlight, if too slow (see ~SYNTAX-HL~). 32 | 33 | 5. You can use ~dos~ memory or ~swap~ memory (but it more slow). 34 | See ~EXT-MEMORY~. 35 | 36 | ///2NAVIGATION 37 | Navigation. 38 | 39 | ~UP~/~DOWN~/~LEFT~/~RIGHT~ - Move cursor to selected 40 | direction on one char. 41 | ~HOME~/~END~ - Move cursor to begin/end of line. 42 | ~PGUP~/~PGDN~ - Move cursor up/down page. 43 | ~Ctrl~+~HOME~ - Move to file start. 44 | ~Ctrl~+~END~ - Move to file end. 45 | 46 | ~Ctrl~+~LEFT~/~RIGHT~ - Move cursor left/right to 47 | next word. 48 | 49 | ~Ctrl~+~L~ - Go to line number. 50 | ~Ctrl~+~O~ - Fast jump to procedure/function (Pascal). 51 | ///2CLIPBOARD 52 | Clipboard operations. 53 | 54 | Windows-clipboard is supported (also present in ~DosBox-X~). 55 | If you have no support for clipboard from environment, ~DWED~ 56 | will use own internal clipboard. 57 | 58 | 59 | ~Shift~ with 60 | ~UP~ 61 | ~LEFT~/~RIGHT~ Use for selection. 62 | ~DOWN~ 63 | ~HOME~/~END~ 64 | 65 | ~Ctrl~+~X~/~C~/~V~ - Cut/Copy/Paste selected text. 66 | ~Ctrl~+~Y~ - Cut current line. 67 | ~Ctrl~+~U~ - Paste clipboard. 68 | ~Shift~+~DEL~ - Cut selected text. 69 | 70 | ~Alt~+~F2~ - Save clipboard to file. 71 | ~Alt~+~F3~ - Load clipboard from file. 72 | ///2SEARCH 73 | Search and Replace. 74 | 75 | ~Ctrl~+~F~ For start case-~in~sensitive search~/~replace. 76 | or ~F7~ 77 | ~Ctrl~+~Shift~+~F~ For start case-sensitive search~/~replace. 78 | 79 | ~Ctrl~+~K~ - Search~/~replace again. 80 | ///2FILE 81 | File operations. 82 | 83 | ~F2~ or ~Ctrl~+~S~ - Save current file. 84 | ~Shift~+~F2~ - Save As. 85 | ~Ctrl~+~Shift~+~S~ - Save ~All~ files. 86 | 87 | ~F3~ - Load file. You can enter non~-~exists name 88 | for a new one. 89 | 90 | ~Alt~+~F4~ - Close file 91 | 92 | ~Alt~+~F2~ - Save clipboard to file. 93 | ~Alt~+~F3~ - Load clipboard from file. 94 | ///2EXTEDITING 95 | Extended editing. 96 | 97 | ~Ctrl~+~Shift~+~PGUP~ - Move line up. 98 | ~Ctrl~+~Shift~+~PGDN~ - Move line down. 99 | ///2WINDOW 100 | Window using. 101 | 102 | ~DWED~ allow edit multiple file at one time. Also, you 103 | have clipboard shared between file. 104 | 105 | ~F6~ - Switch to next file. 106 | ~Alt~+~F6~ - Opened File list window. 107 | 108 | ~Alt~+~F4~ - Close file 109 | 110 | ~Alt~+~F5~ - Show DOS screen. 111 | ///1SYNTAX-HL 112 | Syntax ~h~i~g~h~l~i~g~h~t~. 113 | 114 | ~DWED~ support syntax highlight for next languages: 115 | 116 | ~Assembler~ .asm 117 | ~Sphinx C--~ .c-- .h-- .cmm .hmm 118 | ~Pascal~ .pas 119 | ~Basic~ .bas 120 | ~C~/~C++~ .c .h .cpp .hpp 121 | ~XML/HTML~ .xml .htm 122 | 123 | and ~MS-DOS Shell Scripting~ .bat 124 | 125 | ~Ctrl~+~Alt~+~H~ - to change highlight scheme. 126 | 127 | You can disable highlight, by default, with config option: 128 | ~hl.enable~ = 0 129 | ///1CMD-LINE 130 | Command-line parameters magic. 131 | 132 | If you want load few file - you can specify all of them 133 | into command line. 134 | 135 | You can also pass some configuration parameters. For 136 | example if you have line into ~DWED.CFG~ like this: 137 | 138 | abc ~=~ 4 139 | 140 | You can pass this value via command-line: 141 | 142 | ~DWED.EXE~ ~/~abc~=~4 143 | or 144 | ~DWED.EXE~ ~-~abc~=~4 145 | ///1RUN_USR_SHELL 146 | Run user's shell scripts. 147 | 148 | To run user's shell scripts used keys ~F5~, ~F8~, ~F9~. 149 | To configure actions, put into ~DWED.CFG~ lines like: 150 | 151 | ~usr.def.f5~ = %COMSPEC% 152 | ~usr.def.f8~ = make all 153 | ~usr.def.f9~ = make run 154 | ///1EXT-MEMORY 155 | Ex~t~ended (XMS) ~/~ Ex~p~anded (EMS) memory. 156 | 157 | ~DWED~ use ~XMS~/~EMS~ for cache only (1-2M). But if you want use 158 | full memory - you can do it in indirect way. Just point 159 | your ~TMP~ directory to RamDisk and choose ~swap~ memory. 160 | 161 | Memory model could be configured via config setting: 162 | 163 | ~memory~ = dos~|~swap~ 164 | 165 | Values: 166 | 167 | ~dos~ - Use ~MS-DOS~ conventional memory. Fast. 168 | IRL up to ~350K~. 169 | ~swap~ - Temporary files as string storage (with or 170 | without ~EMS~/~XMS~ cache). In theory, up to ~2G~. 171 | Require free space into ~TMP~ (or ~TEMP~) dir. 172 | 173 | At the same time, you can specify one option only. 174 | By default, value - ~dos~. 175 | 176 | ///1ADDONS 177 | You can active Addons window with ~Alt~+~F10~ or ~F12~. 178 | ///2FASTKBD.COM 179 | Fast keyboard. 180 | 181 | Keyboard works not so fast, because have a big delay into 182 | type metrics. ~AT-BIOS~ allow change it. 183 | 184 | By my opinion, this is not task for text-editor - this is 185 | environment settings. 186 | 187 | So, if you want decrease this delay - you can use next 188 | ~FASTKBD.COM~ file into your ~AUTOEXEC.BAT~: 189 | 190 | 0100: ~B8 05 03~ mov ax~,~ 0305h 191 | 0103: ~31 DB~ xor bx~,~ bx 192 | 0105: ~CD 16~ int 16h 193 | 0107: ~C3~ ret 194 | ///2TETRIS 195 | ~Tetris~ (Video-Game) 196 | 197 | Every text-editor ~must have~ a buildin Tetris. ~TBD~ 198 | ///1CONFIG 199 | Config file 200 | 201 | ~DWED~ have config file ~DWED.CFG~. At first, try to 202 | load from current dir and then - from dir with ~DWED.EXE~. 203 | File format is text - ~key~=~value~ in each line. 204 | 205 | Colors is coded as hex. For example: 206 | 207 | ~color.text~ = ~70~ 208 | 209 | it is mean ~7~ - foreground color and ~0~ - background. 210 | ///2ALL_OPTIONS 211 | All configuration options. 212 | 213 | ~hl.enable~ = 1 214 | ~memory~ = dos~|~swap~ (see ~EXT-MEMORY~) 215 | ~tab_size~ = 8 216 | ~color.top~ = 70 217 | ~color.top_hl~ = 74 218 | ~color.text~ = 07 219 | ~color.text_hl~ = 03 220 | ~color.text_dl~ = 08 221 | ~color.text_sel~ = 17 222 | ~color.menu~ = 1b 223 | ~color.menu_sel~ = 30 224 | ~color.help_menu~ = 07 225 | ~color.help_menu_sel~ = 70 226 | ~color.help~ = 07 227 | ~color.help_hl~ = 03 228 | ~usr.def.f5~ = make clean 229 | ~usr.def.f8~ = make all 230 | ~usr.def.f9~ = make run 231 | ///1LICENSE 232 | The MIT License (MIT) 233 | Copyright (c) 2020 DosWorld 234 | 235 | Full text of license you can read at 236 | 237 | ~htttps://mit-license.org/~ 238 | -------------------------------------------------------------------------------- /SRC/DWEDHELP.HLP: -------------------------------------------------------------------------------- 1 | ABOUT  INTERNALS %NAVIGATION 2 | (CLIPBOARD  SEARCH *FILE ~EXTEDITING sWINDOW lSYNTAX-HL {CMD-LINE /RUN_USR_SHEL ,EXT-MEMORY "ADDONS 'SFASTKBD.COM (TETRIS +^CONFIG ,BALL_OPTIONS /LICENSE 2d$ $ $ $ $ $ ///1ABOUT 3 | About ~DWED~. 4 | 5 | ~DWED~ is a fullfeatured multifile text-editor with 6 | cliboard and syntax highlight support. 7 | 8 | You can use ~DWED~ as ~IDE~ for programming. 9 | 10 | Designed for ~IBM-XT~-grade PC with Intel ~8086~/~88~ CPU 11 | and works in Real Mode ~without~ DPMI, but support editing 12 | up to ~2G~ files. 13 | 14 | (c) ~DosWorld~ 2020 MIT License 15 | 16 | ~https://github.com/DosWorld/dwed/~ 17 | ///1INTERNALS 18 | Few tricks. 19 | 20 | 1. Some time, editor ask you something like 21 | 22 | ~Can i do %something%? (Y/N)~ 23 | 24 | In this case, you can press ~Y~ or ~ENTER~ - to answer ~YES~ 25 | and ~N~ or ~ESC~ - to answer ~NO~. 26 | 27 | 2. For micro-instalation need only two files: ~DWED.EXE~ and 28 | ~DWEDOVL.EXE~. 29 | 30 | 3. You can store ~DWED.CFG~ in local dir, also. 31 | 32 | 4. You can disable highlight, if too slow (see ~SYNTAX-HL~). 33 | 34 | 5. You can use ~dos~ memory or ~swap~ memory (but it more slow). 35 | See ~EXT-MEMORY~. 36 | 37 | ///2NAVIGATION 38 | Navigation. 39 | 40 | ~UP~/~DOWN~/~LEFT~/~RIGHT~ - Move cursor to selected 41 | direction on one char. 42 | ~HOME~/~END~ - Move cursor to begin/end of line. 43 | ~PGUP~/~PGDN~ - Move cursor up/down page. 44 | ~Ctrl~+~HOME~ - Move to file start. 45 | ~Ctrl~+~END~ - Move to file end. 46 | 47 | ~Ctrl~+~LEFT~/~RIGHT~ - Move cursor left/right to 48 | next word. 49 | 50 | ~Ctrl~+~L~ - Go to line number. 51 | ~Ctrl~+~O~ - Fast jump to procedure/function (Pascal). 52 | ///2CLIPBOARD 53 | Clipboard operations. 54 | 55 | Windows-clipboard is supported (also present in ~DosBox-X~). 56 | If you have no support for clipboard from environment, ~DWED~ 57 | will use own internal clipboard. 58 | 59 | 60 | ~Shift~ with 61 | ~UP~ 62 | ~LEFT~/~RIGHT~ Use for selection. 63 | ~DOWN~ 64 | ~HOME~/~END~ 65 | 66 | ~Ctrl~+~X~/~C~/~V~ - Cut/Copy/Paste selected text. 67 | ~Ctrl~+~Y~ - Cut current line. 68 | ~Ctrl~+~U~ - Paste clipboard. 69 | ~Shift~+~DEL~ - Cut selected text. 70 | 71 | ~Alt~+~F2~ - Save clipboard to file. 72 | ~Alt~+~F3~ - Load clipboard from file. 73 | ///2SEARCH 74 | Search and Replace. 75 | 76 | ~Ctrl~+~F~ For start case-~in~sensitive search~/~replace. 77 | or ~F7~ 78 | ~Ctrl~+~Shift~+~F~ For start case-sensitive search~/~replace. 79 | 80 | ~Ctrl~+~K~ - Search~/~replace again. 81 | ///2FILE 82 | File operations. 83 | 84 | ~F2~ or ~Ctrl~+~S~ - Save current file. 85 | ~Shift~+~F2~ - Save As. 86 | ~Ctrl~+~Shift~+~S~ - Save ~All~ files. 87 | 88 | ~F3~ - Load file. You can enter non~-~exists name 89 | for a new one. 90 | 91 | ~Alt~+~F4~ - Close file 92 | 93 | ~Alt~+~F2~ - Save clipboard to file. 94 | ~Alt~+~F3~ - Load clipboard from file. 95 | ///2EXTEDITING 96 | Extended editing. 97 | 98 | ~Ctrl~+~Shift~+~PGUP~ - Move line up. 99 | ~Ctrl~+~Shift~+~PGDN~ - Move line down. 100 | ///2WINDOW 101 | Window using. 102 | 103 | ~DWED~ allow edit multiple file at one time. Also, you 104 | have clipboard shared between file. 105 | 106 | ~F6~ - Switch to next file. 107 | ~Alt~+~F6~ - Opened File list window. 108 | 109 | ~Alt~+~F4~ - Close file 110 | 111 | ~Alt~+~F5~ - Show DOS screen. 112 | ///1SYNTAX-HL 113 | Syntax ~h~i~g~h~l~i~g~h~t~. 114 | 115 | ~DWED~ support syntax highlight for next languages: 116 | 117 | ~Assembler~ .asm 118 | ~Sphinx C--~ .c-- .h-- .cmm .hmm 119 | ~Pascal~ .pas 120 | ~Basic~ .bas 121 | ~C~/~C++~ .c .h .cpp .hpp 122 | ~XML/HTML~ .xml .htm 123 | 124 | and ~MS-DOS Shell Scripting~ .bat 125 | 126 | ~Ctrl~+~Alt~+~H~ - to change highlight scheme. 127 | 128 | You can disable highlight, by default, with config option: 129 | ~hl.enable~ = 0 130 | ///1CMD-LINE 131 | Command-line parameters magic. 132 | 133 | If you want load few file - you can specify all of them 134 | into command line. 135 | 136 | You can also pass some configuration parameters. For 137 | example if you have line into ~DWED.CFG~ like this: 138 | 139 | abc ~=~ 4 140 | 141 | You can pass this value via command-line: 142 | 143 | ~DWED.EXE~ ~/~abc~=~4 144 | or 145 | ~DWED.EXE~ ~-~abc~=~4 146 | ///1RUN_USR_SHELL 147 | Run user's shell scripts. 148 | 149 | To run user's shell scripts used keys ~F5~, ~F8~, ~F9~. 150 | To configure actions, put into ~DWED.CFG~ lines like: 151 | 152 | ~usr.def.f5~ = %COMSPEC% 153 | ~usr.def.f8~ = make all 154 | ~usr.def.f9~ = make run 155 | ///1EXT-MEMORY 156 | Ex~t~ended (XMS) ~/~ Ex~p~anded (EMS) memory. 157 | 158 | ~DWED~ use ~XMS~/~EMS~ for cache only (1-2M). But if you want use 159 | full memory - you can do it in indirect way. Just point 160 | your ~TMP~ directory to RamDisk and choose ~swap~ memory. 161 | 162 | Memory model could be configured via config setting: 163 | 164 | ~memory~ = dos~|~swap~ 165 | 166 | Values: 167 | 168 | ~dos~ - Use ~MS-DOS~ conventional memory. Fast. 169 | IRL up to ~350K~. 170 | ~swap~ - Temporary files as string storage (with or 171 | without ~EMS~/~XMS~ cache). In theory, up to ~2G~. 172 | Require free space into ~TMP~ (or ~TEMP~) dir. 173 | 174 | At the same time, you can specify one option only. 175 | By default, value - ~dos~. 176 | 177 | ///1ADDONS 178 | You can active Addons window with ~Alt~+~F10~ or ~F12~. 179 | ///2FASTKBD.COM 180 | Fast keyboard. 181 | 182 | Keyboard works not so fast, because have a big delay into 183 | type metrics. ~AT-BIOS~ allow change it. 184 | 185 | By my opinion, this is not task for text-editor - this is 186 | environment settings. 187 | 188 | So, if you want decrease this delay - you can use next 189 | ~FASTKBD.COM~ file into your ~AUTOEXEC.BAT~: 190 | 191 | 0100: ~B8 05 03~ mov ax~,~ 0305h 192 | 0103: ~31 DB~ xor bx~,~ bx 193 | 0105: ~CD 16~ int 16h 194 | 0107: ~C3~ ret 195 | ///2TETRIS 196 | ~Tetris~ (Video-Game) 197 | 198 | Every text-editor ~must have~ a buildin Tetris. ~TBD~ 199 | ///1CONFIG 200 | Config file 201 | 202 | ~DWED~ have config file ~DWED.CFG~. At first, try to 203 | load from current dir and then - from dir with ~DWED.EXE~. 204 | File format is text - ~key~=~value~ in each line. 205 | 206 | Colors is coded as hex. For example: 207 | 208 | ~color.text~ = ~70~ 209 | 210 | it is mean ~7~ - foreground color and ~0~ - background. 211 | ///2ALL_OPTIONS 212 | All configuration options. 213 | 214 | ~hl.enable~ = 1 215 | ~memory~ = dos~|~swap~ (see ~EXT-MEMORY~) 216 | ~tab_size~ = 8 217 | ~color.top~ = 70 218 | ~color.top_hl~ = 74 219 | ~color.text~ = 07 220 | ~color.text_hl~ = 03 221 | ~color.text_dl~ = 08 222 | ~color.text_sel~ = 17 223 | ~color.menu~ = 1b 224 | ~color.menu_sel~ = 30 225 | ~color.help_menu~ = 07 226 | ~color.help_menu_sel~ = 70 227 | ~color.help~ = 07 228 | ~color.help_hl~ = 03 229 | ~usr.def.f5~ = make clean 230 | ~usr.def.f8~ = make all 231 | ~usr.def.f9~ = make run 232 | ///1LICENSE 233 | The MIT License (MIT) 234 | Copyright (c) 2020 DosWorld 235 | 236 | Full text of license you can read at 237 | 238 | ~htttps://mit-license.org/~ 239 |  -------------------------------------------------------------------------------- /SRC/DWED.C--: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2022 Viacheslav Komenda 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | */ 25 | 26 | /* 27 | Launcher for DWED 28 | 29 | Don't touch this options, if don't known "why" and "what is it". 30 | */ 31 | 32 | ?argc FALSE 33 | ?parsecommandline FALSE 34 | ?codesize 35 | ?stack 32 36 | ?pragma option TEXE 37 | ?startuptomain 38 | ?pragma option X 39 | ?pragma option OC 40 | ?pragma option DE 41 | ?pragma option OST 42 | ?pragma option STM 43 | ?use8086 44 | 45 | ?define PARENT_PSP 0x16 46 | ?define ENV_IN_PSP 0x2C 47 | ?define ENV_COMSPEC "COMSPEC" 48 | ?define UPTIME_LOW 0x46c 49 | ?define OVL_NAME "DWEDOVL.EXE"; 50 | 51 | char *rndchars = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890"; 52 | char cur_drive; 53 | char cur_dir[256]; 54 | char dwed[256]; 55 | char comspec[256]; 56 | word seed; 57 | 58 | struct { 59 | char sign[5]; 60 | char ini_name[13]; 61 | char cmd[256]; 62 | } dwed_info; 63 | 64 | void PUTS(SI) { 65 | WHILE(TRUE) { 66 | $LODSB; 67 | IF(AL == 0) BREAK; 68 | $INT 0x29; 69 | } 70 | AL = 0x0D; $INT 0x29; 71 | AL = 0x0A; $INT 0x29; 72 | } 73 | 74 | inline char GETCURDRIVE() { 75 | AH = 0x19; $INT 0x21; 76 | } 77 | 78 | inline void SETCURDRIVE(DL) { 79 | AH = 0x0E; $INT 0x21; 80 | } 81 | 82 | inline void GETDIR(DL, SI) { 83 | AX = 0x7147; 84 | $STC; 85 | $PUSH DX, SI; 86 | $INT 0x21; 87 | $POP SI, DX; 88 | IF(CARRYFLAG) { 89 | AH = 0x47; $INT 0x21; 90 | } 91 | } 92 | 93 | inline void CHDIR(DX) { 94 | AX = 0x713B; 95 | $PUSH DX; 96 | $STC; 97 | $INT 0x21; 98 | $POP DX; 99 | IF(CARRYFLAG) { 100 | AH = 0x3b; $INT 0x21; 101 | } 102 | } 103 | 104 | // return ES:DI = env string 105 | inline void ENVSTR(AX) { 106 | ES = DSWORD[ENV_IN_PSP]; 107 | DI = 0; 108 | WHILE (ESBYTE[DI] != 0) { 109 | SI = AX; 110 | CX = 128; 111 | $REPZ 112 | $CMPSB 113 | SI--; 114 | DI--; 115 | BH = DSBYTE[SI]; 116 | BL = ESBYTE[DI]; 117 | IF(BX == '=') RETURN; 118 | WHILE(ESBYTE[DI] != 0) DI++; 119 | DI++; 120 | } 121 | } 122 | 123 | // DX = fname 124 | // BX = args 125 | // CX = env 126 | word SPAWN(DX, BX, CX) { 127 | $PUSH CS 128 | AX = 0x6C; 129 | $PUSH AX 130 | $PUSH CS 131 | AX = 0x5C; 132 | $PUSH AX 133 | $PUSH DS 134 | $PUSH BX; 135 | $PUSH CX; 136 | ES = SS; 137 | BX = SP; 138 | AX = 0x4B00; 139 | $INT 0x21 140 | IF(NOTCARRYFLAG) { 141 | AX = 0; 142 | } 143 | SP += 14; 144 | $PUSH CS, CS; 145 | $POP DS, ES; 146 | } 147 | /* RETURNS: If successful: 148 | AX = 0 149 | If unsuccessful: 150 | AX = error code */ 151 | 152 | inline char GETEXITCODE() { 153 | AH = 0x4d; $INT 0x21; 154 | } 155 | 156 | char RANDOM_CHR() { 157 | $PUSH CX; 158 | 159 | DX = AX = seed; 160 | CL = 7; 161 | AX = AX << CL; 162 | AX ^= DX; 163 | CL = 9; 164 | AX = AX >> CL; 165 | AX ^= DX; 166 | CL = 8; 167 | AX = AX << CL; 168 | AX ^= DX; 169 | seed = AX; 170 | DX = 0; 171 | BX = 38; 172 | $DIV BX; 173 | 174 | DH = 0; 175 | $POP CX; 176 | return rndchars[DX]; 177 | } 178 | 179 | inline char CHECK_INSTALL(BX) { 180 | AL = FALSE; 181 | $PUSH CS; 182 | WHILE(BX != 0) { 183 | DS = BX; 184 | CX = BX; 185 | BX = DSWORD[5]; 186 | BX++; 187 | IF(DSWORD[BX] == 'WD') 188 | IF(DSWORD[BX+2] == 'DE') { 189 | AL = TRUE; 190 | BREAK; 191 | } 192 | BX = DSWORD[PARENT_PSP]; 193 | IF (BX == CX) { 194 | BX = 0; 195 | } 196 | } 197 | $POP DS; 198 | } 199 | 200 | inline void INIT() { 201 | // save current state of FS: drive and dir 202 | cur_drive = @GETCURDRIVE(); 203 | @GETDIR(cur_drive, #cur_dir); 204 | 205 | // Init random session id 206 | $PUSH CS; 207 | DS = 0; 208 | AX = DSWORD[UPTIME_LOW]; 209 | $POP DS; 210 | seed = AX; 211 | // fill signature 212 | BX = #dwed_info.sign; 213 | DSBYTE[BX] = 4; 214 | BX++; 215 | DSWORD[BX] = 'WD'; 216 | DSWORD[BX+2] = 'DE'; 217 | // fill session id 218 | DI = #dwed_info.ini_name; 219 | AL = 12; 220 | $STOSB; 221 | CX = 8; 222 | WHILE(CX != 0) { 223 | RANDOM_CHR(); 224 | $STOSB; 225 | CX--; 226 | } 227 | AL = '.'; 228 | $STOSB; 229 | // ext 230 | CX = 3; 231 | WHILE(CX != 0) { 232 | RANDOM_CHR(); 233 | $STOSB; 234 | CX--; 235 | } 236 | 237 | // Eval path to DWEDOVL.EXE 238 | DS = DSWORD[ENV_IN_PSP]; 239 | SI = 0; 240 | DI = #dwed; 241 | AL = 1; 242 | WHILE(AX != 0) { 243 | AH = AL; 244 | $LODSB; 245 | } 246 | SI += 2; 247 | WHILE(TRUE) { 248 | $LODSB; 249 | IF(AL == 0) BREAK; 250 | $STOSB; 251 | } 252 | $PUSH CS; 253 | $POP DS; 254 | WHILE(DI != #dwed) { 255 | AL = DSWORD[DI]; 256 | IF(AL == ':') BREAK; 257 | IF(AL == '\\') BREAK; 258 | DI--; 259 | } 260 | DI++; 261 | SI = OVL_NAME; 262 | WHILE(TRUE) { 263 | $LODSB; 264 | $STOSB; 265 | IF(AL == 0) BREAK; 266 | } 267 | 268 | // Save COMSPEC env-var 269 | ENVSTR(ENV_COMSPEC); 270 | SI = DI; 271 | DI = #comspec; 272 | $PUSH ES; 273 | $POP DS; 274 | $PUSH CS; 275 | $POP ES; 276 | WHILE(TRUE) { 277 | $LODSB; 278 | $STOSB; 279 | IF(AL == 0) BREAK; 280 | } 281 | $PUSH CS; 282 | $POP DS; 283 | // CP/M BDOS API call - not need :) 284 | DSWORD[5] = #dwed_info; 285 | } 286 | 287 | void main() { 288 | @INIT(); 289 | IF(@CHECK_INSTALL(DSWORD[PARENT_PSP])) { 290 | PUTS("Cycle!"); 291 | AL = 1; 292 | } ELSE { 293 | WHILE(TRUE) { 294 | SPAWN(#dwed, 0x80, DSWORD[ENV_IN_PSP]); 295 | IF(AX != 0) { AL = 1; BREAK; } 296 | @GETEXITCODE(); 297 | IF(AL != 254) BREAK; 298 | // show command line 299 | PUTS(#dwed_info.cmd + 5); 300 | SPAWN(#comspec, #dwed_info.cmd, DSWORD[ENV_IN_PSP]); 301 | // restore FS state 302 | @SETCURDRIVE(cur_drive); 303 | @CHDIR(#cur_dir); 304 | // wait key 305 | AX = 0; $INT 0x16; 306 | } 307 | } 308 | AH = 0x4c; $INT 0x21; 309 | } 310 | -------------------------------------------------------------------------------- /SRC/DWEDSCRU.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2020 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$B-} 23 | unit dwedscru; 24 | 25 | interface 26 | 27 | uses dwedtype; 28 | 29 | procedure update(var ctx : TEditorContext; scru : integer); 30 | 31 | implementation 32 | 33 | uses scr, kminput, str, strutil, strs, dwedhndl, dwedutil, dwedhl; 34 | 35 | function line_full_in_sel(num : longint; y1 : longint; y2 : longint) : boolean; 36 | begin 37 | line_full_in_sel := (num > y1) and (num < y2); 38 | end; 39 | 40 | procedure get_str_part(var ctx : TEditorContext; var s : string); 41 | var len, w, nl, sc : integer; 42 | begin 43 | len := ord(s[0]); 44 | w := ctx.current^.config^.width; 45 | sc := ctx.current^.scrx; 46 | nl:= len - sc; 47 | if nl < 0 then nl := 0; 48 | if nl > w then nl := w; 49 | if (nl <> 0) and (sc<> 0) then move(s[sc + 1], s[1], nl); 50 | s[0] := chr(nl); 51 | end; 52 | 53 | procedure update_full(var ctx : TEditorContext); 54 | var h, w, i, x1, len : integer; 55 | p : EditorStr; 56 | s : string; 57 | sb_y, se_y, clinenum : longint; 58 | sb_x, se_x, scrx : integer; 59 | text_color : byte; 60 | text_sel_color : byte; 61 | selection : boolean; 62 | scrbufofs : pchar; 63 | begin 64 | with ctx.current^ do begin 65 | h := config^.height; 66 | w := config^.width; 67 | p := scrline; 68 | text_sel_color := config^.color.text_sel; 69 | text_color := config^.color.text; 70 | selection := editor.selection; 71 | end; 72 | scrx := ctx.current^.scrx; 73 | if selection then get_sel_coord(ctx, sb_x, sb_y, se_x, se_y); 74 | 75 | scrbufofs := scr.screen + w shl 1; 76 | for i := 1 to h - 1 do begin 77 | clinenum := strs.get_num(p); 78 | strs.get(p, s); 79 | get_str_part(ctx, s); 80 | scr.print(0, i, text_color, s); 81 | scr.cln(ord(s[0]), i, text_color); 82 | if selection then begin 83 | if p = ctx.current^.cline then begin 84 | end else if line_full_in_sel(clinenum, sb_y, se_y) then scr.chcolor(0, i, text_sel_color, w) 85 | else if (sb_y = clinenum) and (sb_x - 1 <= scrx + w) then begin 86 | x1 := sb_x - 1; 87 | if x1 < scrx then x1 := scrx; 88 | dec(x1, scrx); 89 | scr.chcolor(x1, i, text_sel_color, w - x1); 90 | end else if (se_y = clinenum) and (se_x - 1 >= scrx) then begin 91 | len := se_x - 1 - scrx; 92 | if len > w then len := w; 93 | scr.chcolor(0, i, text_sel_color, len); 94 | end; 95 | end; 96 | 97 | high_light(ctx.current^.st, w 98 | , ctx.config.color.text_hl 99 | , text_color 100 | , scrbufofs); 101 | inc(scrbufofs, w shl 1); 102 | p := strs.go_next(p); 103 | end; 104 | end; 105 | 106 | procedure update_cline(var ctx : TEditorContext); 107 | var 108 | sb_y, se_y, clinenum : longint; 109 | sb_x, se_x : integer; 110 | x, xe, len : integer; 111 | scrx, width : integer; 112 | line : string; 113 | begin 114 | with ctx.current^ do begin 115 | scr.cln(0, scry + 1, config^.color.text); 116 | scr.locate(editor.x - 1 - scrx, scry + 1); 117 | end; 118 | x := 0; 119 | line := ctx.current^.editor.line; 120 | get_str_part(ctx, line); 121 | scr.cln(0, ctx.current^.scry + 1, ctx.current^.config^.color.text); 122 | scr.print(0, ctx.current^.scry + 1, ctx.current^.config^.color.text, line); 123 | scrx := ctx.current^.scrx; 124 | width := ctx.current^.config^.width; 125 | 126 | if ctx.current^.editor.selection then begin 127 | get_sel_coord(ctx, sb_x, sb_y, se_x, se_y); 128 | clinenum := strs.get_num(ctx.current^.cline); 129 | len := -1; 130 | if (sb_y = se_y) and (clinenum = sb_y) then begin 131 | if ( sb_x - 1 < scrx + width) 132 | and (se_x - 1 >= scrx) then begin 133 | x := sb_x - 1; 134 | xe := se_x - 1; 135 | if x < scrx then x := scrx; 136 | dec(x, scrx); 137 | dec(xe, scrx); 138 | if xe > width then xe := width; 139 | len := xe - x; 140 | end; 141 | end else if (clinenum = sb_y) then begin 142 | x := sb_x - 1; 143 | if x < scrx + width then begin 144 | if x < scrx then x := 0 else dec(x, scrx); 145 | len := width - x; 146 | end; 147 | end else if (clinenum = se_y) then begin 148 | x := 0; 149 | if se_x - 1 > scrx then begin 150 | len := se_x - 1 - scrx; 151 | if len > width then len := width; 152 | end; 153 | end; 154 | if len > 0 then scr.chcolor(x, ctx.current^.scry + 1, ctx.current^.config^.color.text_sel, len); 155 | end; 156 | 157 | with ctx.current^ do begin 158 | high_light(st, config^.width 159 | , config^.color.text_hl 160 | , config^.color.text 161 | , @scr.screen[(config^.width * (scry + 1)) shl 1]); 162 | end; 163 | end; 164 | 165 | procedure update_scroll(var ctx : TEditorContext; is_up : boolean); 166 | begin 167 | if is_up then scr.scroll_up(0, 1, ctx.config.width, ctx.config.height - 1, 1) 168 | else scr.scroll_down(0, 1, ctx.config.width, ctx.config.height - 1, 1); 169 | end; 170 | 171 | procedure update_top(var ctx : TEditorContext); 172 | var ch, i : char; 173 | endline : string; 174 | fname : string; 175 | total : string; 176 | char_code : string; 177 | begin 178 | ch := ' '; 179 | i := 'O'; 180 | if ctx.current^.chg or ctx.current^.editor.chg then ch := '*'; 181 | if ctx.ins then i := 'I'; 182 | if ctx.current^.editor.x <= length(ctx.current^.editor.line) then begin 183 | char_code := hexb(ord(ctx.current^.editor.line[ctx.current^.editor.x])); 184 | end else char_code := ''; 185 | total := ltoa(ctx.current^.total); 186 | endline := concat( 187 | char_code, ' ', 188 | lpad(itoa(ctx.current^.editor.x), 3), ' ', 189 | lpad(ltoa(strs.get_num(ctx.current^.cline)), length(total)), 190 | '/', total, ' ', ch, i,' '); 191 | 192 | fname := ' ' + trim(ctx.current^.sfname); 193 | endline := lpad(endline, ctx.current^.config^.width - length(fname)); 194 | 195 | scr.cln(0, 0, ctx.current^.config^.color.top); 196 | scr.print(0, 0, ctx.current^.config^.color.top, fname + endline); 197 | end; 198 | 199 | procedure update(var ctx : TEditorContext; scru : integer); 200 | begin 201 | if scru <> SCRU_NONE then begin 202 | if scru >= SCRU_FULL then update_full(ctx); 203 | 204 | if scru = SCRU_SD then update_scroll(ctx, false) 205 | else if scru = SCRU_SU then update_scroll(ctx, true); 206 | 207 | if scru >= SCRU_CLINE then update_cline(ctx); 208 | if scru >= SCRU_TOP then update_top(ctx); 209 | if ctx.ins then scr.cursor_on else scr.cursor_big; 210 | scr.show; 211 | end; 212 | end; 213 | 214 | end. 215 | -------------------------------------------------------------------------------- /SRC/HELP.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2022 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$A-} 23 | unit help; 24 | 25 | interface 26 | 27 | type 28 | PHelpTopic = ^THelpTopic; 29 | THelpTopic = record 30 | name : array[1..12] of char; 31 | recno : word; 32 | ofs : byte; 33 | lvl : byte; 34 | end; 35 | 36 | PHelpTopicList = ^THelpTopicList; 37 | THelpTopicList = record 38 | topic : THelpTopic; 39 | htext : pchar; 40 | hlen : word; 41 | next : PHelpTopicList; 42 | end; 43 | 44 | function from_file(fname : string):PHelpTopicList; 45 | function from_memory(p : pointer):PHelpTopicList; 46 | 47 | function find(root : PHelpTopicList; topic_name : string):PHelpTopicList; 48 | 49 | procedure free(hlp : PHelpTopicList); 50 | 51 | procedure compile(ifname, ofname : string); 52 | 53 | implementation 54 | 55 | uses system2; 56 | 57 | type 58 | 59 | PHelpIntTopic = ^THelpIntTopic; 60 | THelpIntTopic = record 61 | name : string; 62 | ofs : longint; 63 | lvl : byte; 64 | next : PHelpIntTopic; 65 | end; 66 | 67 | function is_digit(c : char):boolean; 68 | begin 69 | is_digit := c in ['0'..'9']; 70 | end; 71 | 72 | procedure compile(ifname, ofname : string); 73 | var ifile : bfile; 74 | ofile : bfile; 75 | s : string; 76 | tcount : word; 77 | root, last, cur : PHelpIntTopic; 78 | ofs : longint; 79 | topic : THelpTopic; 80 | i, l : integer; 81 | begin 82 | tcount := 0; root := nil; last := nil; ofs := 0; 83 | assign(ifile, ifname); 84 | reset(ifile); 85 | if ifile.ioresult <> 0 then exit; 86 | while not eof(ifile) do begin 87 | readln(ifile, s); 88 | l := length(s); 89 | if length(s)>4 then begin 90 | if (s[1] = '/') and (s[2] = '/') and (s[3] = '/') and is_digit(s[4]) then begin 91 | getmem(cur, sizeof(THelpIntTopic)); 92 | cur^.lvl := ord(s[4]) - ord('0'); 93 | cur^.name := copy(s, 5, length(s)-4); 94 | cur^.ofs := ofs + length(s); 95 | cur^.next := nil; 96 | if root = nil then root := cur; 97 | if last <> nil then last^.next := cur; 98 | last := cur; 99 | inc(tcount); 100 | end; 101 | end; 102 | inc(ofs, length(s) + 2); 103 | end; 104 | inc(tcount); 105 | 106 | while ((tcount * sizeof(THelpTopic)) and $7f) <> 0 do begin 107 | inc(tcount); 108 | end; 109 | 110 | assign(ofile, ofname); 111 | rewrite(ofile); 112 | 113 | ofs := sizeof(THelpTopic) * tcount; 114 | cur := root; 115 | while cur <> nil do begin 116 | inc(cur^.ofs, ofs); 117 | topic.recno := cur^.ofs shr 7; 118 | topic.ofs := cur^.ofs and $7f; 119 | topic.lvl := cur^.lvl; 120 | fillchar(topic.name, 12, ' '); 121 | l := length(cur^.name); 122 | if l > 12 then l := 12; 123 | for i:=1 to l do topic.name[i] := upcase(cur^.name[i]); 124 | blockwrite(ofile, topic, sizeof(THelpTopic)); 125 | dec(tcount); 126 | cur := cur^.next; 127 | end; 128 | topic.recno := 0; 129 | topic.ofs := 0; 130 | topic.lvl := 0; 131 | fillchar(topic.name, 12, ' '); 132 | topic.name[1] := '$'; 133 | while tcount <> 0 do begin 134 | blockwrite(ofile, topic, sizeof(THelpTopic)); 135 | dec(tcount); 136 | end; 137 | 138 | seek(ifile, 0); 139 | blockcopy(ifile, ofile, filesize(ifile)); 140 | l := 128 - (filepos(ofile) and $7f); 141 | fillchar(s[1], l, #$1a); 142 | s[0] := chr(l); 143 | blockwrite(ofile, s[1], l); 144 | close(ifile); 145 | close(ofile); 146 | while root <> nil do begin 147 | cur := root; 148 | root := root^.next; 149 | freemem(cur, sizeof(THelpIntTopic)); 150 | end; 151 | end; 152 | 153 | function find(root : PHelpTopicList; topic_name : string) : PHelpTopicList; 154 | var name : array[1..12] of char; 155 | i, l : integer; 156 | found : boolean; 157 | r : PHelpTopicList; 158 | begin 159 | fillchar(name, 12, ' '); 160 | l := length(topic_name); 161 | if l > 12 then l := 12; 162 | for i:=1 to l do name[i] := upcase(topic_name[i]); 163 | 164 | r := root; 165 | found := false; 166 | while (not found) and (r <> nil) do begin 167 | found := true; 168 | i := 1; 169 | while i <= 12 do begin 170 | if name[i] <> r^.topic.name[i] then begin found := false; break; end; 171 | inc(i); 172 | end; 173 | if found then begin find := r; exit; end; 174 | r := r^.next; 175 | end; 176 | find := nil; 177 | end; 178 | 179 | function from_file(fname : string) : PHelpTopicList; 180 | var 181 | f : bfile; 182 | r, l, c : PHelpTopicList; 183 | nt, fs : longint; 184 | begin 185 | r := nil; c := nil; l := nil; 186 | assign(f, fname); 187 | reset(f); 188 | while true do begin 189 | getmem(c, sizeof(THelpTopicList)); 190 | blockread(f, c^.topic, sizeof(THelpTopic)); 191 | c^.next := nil; 192 | c^.htext := nil; 193 | c^.hlen := 0; 194 | if r = nil then r := c; 195 | if l <> nil then l^.next := c; 196 | if (c^.topic.recno = 0) and (c^.topic.ofs = 0) and (c^.topic.ofs = 0) then break; 197 | l := c; 198 | end; 199 | fs := filesize(f); 200 | c := r; 201 | while c <> nil do begin 202 | if (c^.topic.recno = 0) and (c^.topic.ofs = 0) and (c^.topic.ofs = 0) then break; 203 | if (c^.next^.topic.recno = 0) and (c^.next^.topic.ofs = 0) and (c^.next^.topic.ofs = 0) then nt := fs 204 | else nt := (c^.next^.topic.recno shl 7) + c^.next^.topic.ofs; 205 | c^.hlen := nt - ((c^.topic.recno shl 7) + c^.topic.ofs) + 1; 206 | getmem(c^.htext, c^.hlen); 207 | seek(f, (c^.topic.recno shl 7) + c^.topic.ofs); 208 | blockread(f, c^.htext^, c^.hlen - 1); 209 | c^.htext[c^.hlen - 1] := #0; 210 | c := c^.next; 211 | end; 212 | close(f); 213 | from_file := r; 214 | end; 215 | 216 | function from_memory(p : pointer) : PHelpTopicList; 217 | var rp, ep : pchar; 218 | r, l, c : PHelpTopicList; 219 | nt, fs : longint; 220 | begin 221 | r := nil; c := nil; l := nil; 222 | rp := p; 223 | while true do begin 224 | getmem(c, sizeof(THelpTopicList)); 225 | move(rp^, c^.topic, sizeof(THelpTopic)); 226 | inc(rp, sizeof(THelpTopic)); 227 | c^.next := nil; 228 | c^.htext := nil; 229 | c^.hlen := 0; 230 | if r = nil then r := c; 231 | if l <> nil then l^.next := c; 232 | if (c^.topic.recno = 0) and (c^.topic.ofs = 0) and (c^.topic.ofs = 0) then break; 233 | l := c; 234 | end; 235 | ep := rp; 236 | while ep^ <> #$1a do inc(ep); 237 | rp := p; 238 | fs := ep - rp; 239 | c := r; 240 | while c <> nil do begin 241 | if (c^.topic.recno = 0) and (c^.topic.ofs = 0) and (c^.topic.ofs = 0) then break; 242 | if (c^.next^.topic.recno = 0) and (c^.next^.topic.ofs = 0) and (c^.next^.topic.ofs = 0) then nt := fs 243 | else nt := (c^.next^.topic.recno shl 7) + c^.next^.topic.ofs; 244 | c^.hlen := nt - ((c^.topic.recno shl 7) + c^.topic.ofs) + 1; 245 | getmem(c^.htext, c^.hlen); 246 | move(rp[(c^.topic.recno shl 7) + c^.topic.ofs], c^.htext[0], c^.hlen - 1); 247 | c^.htext[c^.hlen - 1] := #0; 248 | c := c^.next; 249 | end; 250 | from_memory := r; 251 | end; 252 | 253 | procedure free(hlp : PHelpTopicList); 254 | var h : PHelpTopicList; 255 | begin 256 | while hlp <> nil do begin 257 | h := hlp; 258 | hlp := hlp^.next; 259 | if h^.htext <> nil then freemem(h^.htext, h^.hlen); 260 | freemem(h, sizeof(THelpTopicList)); 261 | end; 262 | end; 263 | 264 | end. 265 | -------------------------------------------------------------------------------- /SRC/STRS.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2022 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$I-} 23 | unit strs; 24 | 25 | { proxy for string storage calls } 26 | 27 | interface 28 | 29 | type 30 | MemoryType = (MT_DOS, MT_SWAP, MT_SXMS); 31 | EditorStr = pointer; 32 | 33 | procedure init(mType : MemoryType); 34 | procedure done; 35 | 36 | function new : EditorStr; 37 | 38 | function from_file(fname : string; tab_size : integer; var errCode : integer; scrupdate : pointer) : EditorStr; 39 | procedure to_file(fname : string; r : EditorStr; var errCode : integer; scrupdate : pointer); 40 | 41 | function create(next, prev : EditorStr; var body : string) : EditorStr; 42 | procedure free(r : EditorStr); 43 | 44 | function put(r : EditorStr; var body : string) : EditorStr; 45 | procedure get(r : EditorStr; var dest : string); 46 | function delete(r : EditorStr; num_from, num_to : longint) : EditorStr; 47 | function merge(r : EditorStr) : EditorStr; 48 | function is_first(r : EditorStr) : boolean; 49 | function is_last(r : EditorStr) : boolean; 50 | 51 | function go_first(r : EditorStr) : EditorStr; 52 | function go_last(r : EditorStr) : EditorStr; 53 | 54 | function go_prev(r : EditorStr) : EditorStr; 55 | function go_next(r : EditorStr) : EditorStr; 56 | 57 | function renum(r : EditorStr) : longint; 58 | function get_num(r : EditorStr) : longint; 59 | function find_num(r : EditorStr; num : longint) : EditorStr; 60 | 61 | function append(r : EditorStr; var pos : integer; p : pchar; var lnum:word) : EditorStr; 62 | function split(r : EditorStr; pos : integer) : EditorStr; 63 | 64 | function is_nil(r : EditorStr) : boolean; 65 | 66 | implementation 67 | 68 | uses system2, scr, strsdos, strssxms, strsswap, dwedtype, str, strutil; 69 | 70 | const 71 | memType : MemoryType = MT_DOS; 72 | 73 | procedure init(mType : MemoryType); 74 | begin 75 | memType := mType; 76 | if mType = MT_SXMS then strssxms.init 77 | else if mType = MT_SWAP then strsswap.init 78 | else strsdos.init; 79 | end; 80 | 81 | procedure done; 82 | begin 83 | if memType = MT_SXMS then strssxms.done 84 | else if memType = MT_SWAP then strsswap.done 85 | else strsdos.done; 86 | end; 87 | 88 | function put(r : EditorStr; var body : string) : EditorStr; 89 | begin 90 | if memType = MT_SXMS then put := EditorStr(strssxms.put(dword(r), body)) 91 | else if memType = MT_SWAP then put := EditorStr(strsswap.put(dword(r), body)) 92 | else put := EditorStr(strsdos.put(pointer(r), body)); 93 | end; 94 | 95 | function create(next, prev : EditorStr; var body : string) : EditorStr; 96 | begin 97 | if memType = MT_SXMS then create := EditorStr(strssxms.create(dword(next), dword(prev), body)) 98 | else if memType = MT_SWAP then create := EditorStr(strsswap.create(dword(next), dword(prev), body)) 99 | else create := EditorStr(strsdos.create(pointer(next), pointer(prev), body)); 100 | end; 101 | 102 | function from_file(fname : string; tab_size : integer; var errCode : integer; scrupdate : pointer) : EditorStr; 103 | begin 104 | spinner_start; 105 | errCode := 0; 106 | if not FileExists(fname) then begin 107 | errCode := 104; 108 | from_file := EditorStr(strs.new); 109 | end else if memType = MT_SXMS then 110 | from_file := EditorStr(strssxms.from_file(fname, tab_size, errCode, scrupdate)) 111 | else if memType = MT_SWAP then 112 | from_file := EditorStr(strsswap.from_file(fname, tab_size, errCode, scrupdate)) 113 | else 114 | from_file := EditorStr(strsdos.from_file(fname, tab_size, errCode, scrupdate)); 115 | spinner_stop; 116 | end; 117 | 118 | procedure to_file(fname : string; r : EditorStr; var errCode : integer; scrupdate : pointer); 119 | var f : bfile; 120 | fnamebak : string; 121 | begin 122 | spinner_start; 123 | errCode := 0; 124 | if FileExists(fname) then begin 125 | fnamebak := change_ext(fname, '.bak'); 126 | if FileExists(fnamebak) then FileDelete(fnamebak); 127 | assign(f, fname); 128 | rename(f, fnamebak); 129 | end; 130 | 131 | if memType = MT_SXMS then 132 | strssxms.to_file(fname, dword(r), errCode, scrupdate) 133 | else if memType = MT_SWAP then 134 | strsswap.to_file(fname, dword(r), errCode, scrupdate) 135 | else 136 | strsdos.to_file(fname, pointer(r), errCode, scrupdate); 137 | spinner_stop; 138 | end; 139 | 140 | function new : EditorStr; 141 | begin 142 | if memType = MT_SXMS then new := EditorStr(strssxms.new) 143 | else if memType = MT_SWAP then new := EditorStr(strsswap.new) 144 | else new := EditorStr(strsdos.new); 145 | end; 146 | 147 | procedure get(r : EditorStr; var dest : string); 148 | begin 149 | if memType = MT_SXMS then strssxms.get(dword(r), dest) 150 | else if memType = MT_SWAP then strsswap.get(dword(r), dest) 151 | else strsdos.get(pointer(r), dest); 152 | end; 153 | 154 | function is_first(r : EditorStr) : boolean; 155 | begin 156 | if memType = MT_SXMS then is_first := strssxms.is_first(dword(r)) 157 | else if memType = MT_SWAP then is_first := strsswap.is_first(dword(r)) 158 | else is_first := strsdos.is_first(pointer(r)); 159 | end; 160 | 161 | function is_last(r : EditorStr) : boolean; 162 | begin 163 | if memType = MT_SXMS then is_last := strssxms.is_last(dword(r)) 164 | else if memType = MT_SWAP then is_last := strsswap.is_last(dword(r)) 165 | else is_last := strsdos.is_last(pointer(r)); 166 | end; 167 | 168 | function go_first(r : EditorStr) : EditorStr; 169 | begin 170 | if memType = MT_SXMS then go_first := EditorStr(strssxms.go_first(dword(r))) 171 | else if memType = MT_SWAP then go_first := EditorStr(strsswap.go_first(dword(r))) 172 | else go_first := EditorStr(strsdos.go_first(pointer(r))); 173 | end; 174 | 175 | function go_last(r : EditorStr) : EditorStr; 176 | begin 177 | if memType = MT_SXMS then go_last := EditorStr(strssxms.go_last(dword(r))) 178 | else if memType = MT_SWAP then go_last := EditorStr(strsswap.go_last(dword(r))) 179 | else go_last := EditorStr(strsdos.go_last(pointer(r))); 180 | end; 181 | 182 | function go_prev(r : EditorStr) : EditorStr; 183 | begin 184 | if memType = MT_SXMS then go_prev := EditorStr(strssxms.go_prev(dword(r))) 185 | else if memType = MT_SWAP then go_prev := EditorStr(strsswap.go_prev(dword(r))) 186 | else go_prev := EditorStr(strsdos.go_prev(pointer(r))); 187 | end; 188 | 189 | function go_next(r : EditorStr) : EditorStr; 190 | begin 191 | if memType = MT_SXMS then go_next := EditorStr(strssxms.go_next(dword(r))) 192 | else if memType = MT_SWAP then go_next := EditorStr(strsswap.go_next(dword(r))) 193 | else go_next := EditorStr(strsdos.go_next(pointer(r))); 194 | end; 195 | 196 | procedure free(r : EditorStr); 197 | begin 198 | if memType = MT_SXMS then strssxms.free(dword(r)) 199 | else if memType = MT_SWAP then strsswap.free(dword(r)) 200 | else strsdos.free(pointer(r)); 201 | end; 202 | 203 | function renum(r : EditorStr) : dword; 204 | begin 205 | spinner_start; 206 | if memType = MT_SXMS then renum := strssxms.renum(dword(r)) 207 | else if memType = MT_SWAP then renum := strsswap.renum(dword(r)) 208 | else renum := strsdos.renum(pointer(r)); 209 | spinner_stop; 210 | end; 211 | 212 | function get_num(r : EditorStr) : dword; 213 | begin 214 | if memType = MT_SXMS then get_num := strssxms.get_num(dword(r)) 215 | else if memType = MT_SWAP then get_num := strsswap.get_num(dword(r)) 216 | else get_num := strsdos.get_num(pointer(r)); 217 | end; 218 | 219 | function find_num(r : EditorStr; num : dword) : EditorStr; 220 | begin 221 | spinner_start; 222 | while not is_nil(r) do begin 223 | if num = strs.get_num(r) then break; 224 | r := strs.go_next(r); 225 | end; 226 | spinner_stop; 227 | find_num := r; 228 | end; 229 | 230 | function delete(r : EditorStr; num_from, num_to : dword) : EditorStr; 231 | begin 232 | spinner_start; 233 | if memType = MT_SXMS then delete := EditorStr(strssxms.delete(dword(r), num_from, num_to)) 234 | else if memType = MT_SWAP then delete := EditorStr(strsswap.delete(dword(r), num_from, num_to)) 235 | else delete := EditorStr(strsdos.delete(pointer(r), num_from, num_to)); 236 | spinner_stop; 237 | end; 238 | 239 | function merge(r : EditorStr) : EditorStr; 240 | begin 241 | if memType = MT_SXMS then merge := EditorStr(strssxms.merge(dword(r))) 242 | else if memType = MT_SWAP then merge := EditorStr(strsswap.merge(dword(r))) 243 | else merge := EditorStr(strsdos.merge(pointer(r))); 244 | end; 245 | 246 | function append(r : EditorStr; var pos : integer; p : pchar; var lnum:word) : EditorStr; 247 | begin 248 | spinner_start; 249 | if memType = MT_SXMS then append := EditorStr(strssxms.append(dword(r), pos, p, lnum)) 250 | else if memType = MT_SWAP then append := EditorStr(strsswap.append(dword(r), pos, p, lnum)) 251 | else append := EditorStr(strsdos.append(pointer(r), pos, p, lnum)); 252 | spinner_stop; 253 | end; 254 | 255 | function split(r : EditorStr; pos : integer) : EditorStr; 256 | begin 257 | if memType = MT_SXMS then split := EditorStr(strssxms.split(dword(r), pos)) 258 | else if memType = MT_SWAP then split := EditorStr(strsswap.split(dword(r), pos)) 259 | else split := strsdos.split(pointer(r), pos); 260 | end; 261 | 262 | function is_nil(r : EditorStr) : boolean; 263 | begin 264 | if memType = MT_SXMS then is_nil := strssxms.is_nil(dword(r)) 265 | else if memType = MT_SWAP then is_nil := strsswap.is_nil(dword(r)) 266 | else is_nil := strsdos.is_nil(pointer(r)); 267 | end; 268 | 269 | end. 270 | -------------------------------------------------------------------------------- /SRC/DWEDADDO.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2020 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | unit dwedaddo; 23 | 24 | interface 25 | 26 | uses dwedtype; 27 | 28 | procedure addons_window(var ctx : TEditorContext); 29 | procedure ascii_table(var ctx : TEditorContext); 30 | procedure calculator(var ctx : TEditorContext); 31 | 32 | implementation 33 | 34 | uses system2, strutil, str, kminput, event, scr, scrui, strs; 35 | 36 | type 37 | RadixType = (RADIX2, RADIX10, RADIX16); 38 | 39 | const addons_menu : pchar = 40 | ' ASCII-Table Ctrl+Alt+A ' + #$0A + 41 | ' Calculator Ctrl+Alt+C '; 42 | 43 | procedure addons_window(var ctx : TEditorContext); 44 | var sitem : integer; 45 | e : TEvent; 46 | begin 47 | scr.push; 48 | sitem := 0; 49 | while true do begin 50 | scrui.vmenu(e, 1, 2, 33, scr.getheight - 3, 51 | ctx.config.color.menu, 52 | ctx.config.color.menu_sel, 53 | 'Addons', 54 | addons_menu, sitem); 55 | if e.etype in [MOUSE_PRESS_B1, MOUSE_PRESS_B2] then begin sitem := -1; break; end; 56 | if e.etype <> KEYBOARD then continue; 57 | if e.scancode = SCAN_ESC then begin sitem := -1; break; end; 58 | if (e.scancode = SCAN_ENTER) or (e.ascii = ' ') then break; 59 | end; 60 | scr.pop; 61 | if sitem = -1 then exit; 62 | case sitem of 63 | 0 : ascii_table(ctx); 64 | 1 : calculator(ctx); 65 | end; 66 | end; 67 | 68 | procedure insert_str(var ctx : TEditorContext; str : string); 69 | var line_len : integer; 70 | str_len : integer; 71 | begin 72 | line_len := length(ctx.current^.editor.line); 73 | str_len := length(str); 74 | if line_len + str_len > 255 then str_len := 255 - line_len; 75 | str := copy(str, 1, str_len); 76 | 77 | System.insert(str, ctx.current^.editor.line, ctx.current^.editor.x); 78 | ctx.current^.editor.chg := true; 79 | ctx.current^.chg := true; 80 | inc(ctx.current^.editor.x, str_len); 81 | end; 82 | 83 | const 84 | ascii_tbl_sel : byte = 0; 85 | 86 | procedure ascii_table(var ctx : TEditorContext); 87 | var x, y, i, j : integer; 88 | b : boolean; 89 | color, cb : byte; 90 | ch : char; 91 | e : TEvent; 92 | begin 93 | x := (scr.getwidth - 50) shr 1; y := (scr.getheight - 22) shr 1; 94 | scrui.box(x, y, 50, 22, $1b); 95 | while true do begin 96 | for i := 1 to 20 do scr.hprint(x + 1, y + i, $1b, ' ', 48); 97 | for i := 0 to 15 do begin 98 | b := (i and 1) = 0; 99 | for j := 0 to 15 do begin 100 | if b then color := $17 else color := $1e; 101 | cb := j or (i shl 4); 102 | scr.hprint(x + 2 + j * 3, y + 3 + i, color, chr(cb) , 1); 103 | if cb = ascii_tbl_sel then scr.chcolor(x + 1 + j * 3, y + 3 + i, $31, 3); 104 | b := not b; 105 | end; 106 | end; 107 | scr.hprint(x + 1, y + 2, $1b, #$C4 , 48); 108 | scr.hprint(x + 1, y + 19, $1b, #$C4 , 48); 109 | printhl(x + 2, y + 1, $1b, $1e, concat( 110 | 'Hex: ~', 111 | hexb(ascii_tbl_sel), 112 | '~ Dec: ~', 113 | lpad(itoa(ascii_tbl_sel), 3), 114 | '~ Bin: ~', 115 | binb(ascii_tbl_sel), 116 | '~ Oct: ~', 117 | octb(ascii_tbl_sel), 118 | '~ Color' 119 | )); 120 | scr.chcolor(x + 43, y + 1, ascii_tbl_sel, 5); 121 | scr.printhl(x + 2, y + 20, $1b, $1e, 122 | '~'+#$11+#$D9+'~ Enter symbol ' + #$B3 + 123 | ' ~Shift~+~'+#$11+#$D9+'~ Enter hex code' 124 | ); 125 | scr.show; 126 | while true do begin 127 | wait_event(e); 128 | if e.etype = KEYBOARD then break; 129 | end; 130 | case e.scancode of 131 | SCAN_UP: dec(ascii_tbl_sel, 16); 132 | SCAN_DOWN: inc(ascii_tbl_sel, 16); 133 | SCAN_LEFT: ascii_tbl_sel := (ascii_tbl_sel and $F0) or ((ascii_tbl_sel - 1) and $0F); 134 | SCAN_RIGHT: ascii_tbl_sel := (ascii_tbl_sel and $F0) or ((ascii_tbl_sel + 1) and $0F); 135 | SCAN_ENTER: begin 136 | if e.ctrl_keys = key_shift then begin 137 | insert_str(ctx, '' + hexb(ascii_tbl_sel)); 138 | break; 139 | end else begin 140 | if (ascii_tbl_sel = 9) 141 | or (ascii_tbl_sel = 0) 142 | or (ascii_tbl_sel = $0a) 143 | or (ascii_tbl_sel = $0d) then continue; 144 | insert_str(ctx, '' + chr(ascii_tbl_sel)); 145 | break; 146 | end; 147 | end; 148 | SCAN_ESC: break; 149 | else begin 150 | ch := upcase(e.ascii); 151 | if ch in ['0'..'9'] then 152 | ascii_tbl_sel := (ascii_tbl_sel shl 4) 153 | or ((ord(ch) - ord('0')) and $0F) 154 | else if ch in ['A'..'F'] then 155 | ascii_tbl_sel := (ascii_tbl_sel shl 4) 156 | or ((ord(ch) - ord('A') + 10) and $0F); 157 | end; 158 | end; 159 | end; 160 | end; 161 | 162 | const 163 | calc_op1 : longint = 0; 164 | calc_op2 : longint = 0; 165 | calc_op : char = ' '; 166 | radix : RadixType = RADIX10; 167 | 168 | procedure calculator(var ctx : TEditorContext); 169 | var x, y, i : integer; 170 | key : word; 171 | ch : char; 172 | e : TEvent; 173 | begin 174 | scr.set_cursor(scr.cursor); 175 | x := (scr.getwidth - 41) shr 1; 176 | y := (scr.getheight - 10) shr 1; 177 | scrui.box(x, y, 41, 10, $1b); 178 | for i := 1 to 8 do scr.hprint(x + 1, y + i, $1b, ' ', 39); 179 | scr.printhl(x + 2, y + 1, $1b, $1e, 'Dec~:'); 180 | scr.printhl(x + 2, y + 2, $1b, $1e, 'Hex~:'); 181 | scr.printhl(x + 2, y + 3, $1b, $1e, 'Bin~:'); 182 | scr.hprint(x + 1, y + 4, $1b, #$C4 , 39); 183 | scr.printhl(x + 2, y + 5, $1b, $1e, '~+~ Add ~-~ Sub ~*~ Mul ~/~ Div ~M~ Mod'); 184 | scr.printhl(x + 2, y + 6, $1b, $1e, '~&~ And ~|~ Or ~^~ Xor ~!~ Not ~N~ Neg'); 185 | scr.hprint(x + 1, y + 7, $1b, #$C4 , 39); 186 | scr.printhl(x + 2, y + 8, $1b, $1e, '~Spc~ Clr ~'+#$1D+'~ Rdx ~Shift~+~'+#$11+#$D9+'~ Enter value'); 187 | while true do begin 188 | scr.vprint(x + 6, y + 1, $1b, ' ', 3); 189 | if radix = RADIX10 then begin scr.print(x + 6, y + 1, $1e, '' + #$10); locate(x + 39, y + 1); end 190 | else if radix = RADIX16 then begin scr.print(x + 6, y + 2, $1e, '' + #$10); locate(x + 39, y + 2); end 191 | else if radix = RADIX2 then begin scr.print(x + 6, y + 3, $1e, '' + #$10); locate(x + 39, y + 3); end; 192 | scr.print(x + 7, y + 1, $1b, lpad(ltoa(calc_op1), 32)); 193 | scr.print(x + 7, y + 2, $1b, lpad(hexdw(calc_op1), 32)); 194 | scr.print(x + 7, y + 3, $1b, lpad(bindw(calc_op1), 32)); 195 | 196 | scr.chcolor(x + 7 + 20, y + 1, $1A, 3); 197 | scr.chcolor(x + 7 + 26, y + 1, $1A, 3); 198 | 199 | scr.chcolor(x + 7 + 24, y + 2, $1E, 2); 200 | scr.chcolor(x + 7 + 28, y + 2, $1E, 2); 201 | scr.chcolor(x + 7, y + 3, $1E, 8); 202 | scr.chcolor(x + 7 + 16, y + 3, $1E, 8); 203 | scr.show; 204 | while true do begin 205 | wait_event(e); 206 | if e.etype = KEYBOARD then break; 207 | end; 208 | case e.scancode of 209 | SCAN_ESC: break; 210 | SCAN_ENTER: begin 211 | if e.ctrl_keys <> key_shift then begin 212 | case calc_op of 213 | '+': calc_op1 := calc_op2 + calc_op1; 214 | '-': calc_op1 := calc_op2 - calc_op1; 215 | '*': calc_op1 := calc_op2 * calc_op1; 216 | '/': calc_op1 := calc_op2 div calc_op1; 217 | 'M': calc_op1 := calc_op2 mod calc_op1; 218 | '&': calc_op1 := calc_op2 and calc_op1; 219 | '|': calc_op1 := calc_op2 or calc_op1; 220 | '^': calc_op1 := calc_op2 xor calc_op1; 221 | end; 222 | end else begin 223 | if radix = RADIX10 then insert_str(ctx, ltoa(calc_op1)) 224 | else if radix = RADIX16 then insert_str(ctx, hexdw(calc_op1)) 225 | else if radix = RADIX2 then insert_str(ctx, bindw(calc_op1)); 226 | break; 227 | end; 228 | end; 229 | SCAN_TAB: begin 230 | if radix = RADIX10 then radix := RADIX16 231 | else if radix = RADIX16 then radix := RADIX2 232 | else if radix = RADIX2 then radix := RADIX10; 233 | end; 234 | SCAN_BS: begin 235 | if radix = RADIX2 then calc_op1 := calc_op1 shr 1 236 | else if radix = RADIX10 then calc_op1 := calc_op1 div 10 237 | else if radix = RADIX16 then calc_op1 := calc_op1 shr 8; 238 | end; 239 | end; 240 | ch := upcase(e.ascii); 241 | case ch of 242 | ' ': begin calc_op1 := 0; continue; end; 243 | '+','-','*','/','M','&','|','^': begin calc_op := ch; calc_op2 := calc_op1; calc_op1 := 0; continue; end; 244 | 'N': calc_op1 := -calc_op1; 245 | '!': calc_op1 := calc_op1 xor $FFFFFFFF; 246 | end; 247 | case radix of 248 | RADIX2 : begin 249 | if ch in ['0'..'1'] then calc_op1 := (calc_op1 shl 1) or (ord(ch) - ord('0')); 250 | end; 251 | RADIX10 : begin 252 | if ch in ['0'..'9'] then begin 253 | if calc_op1 >= 0 then calc_op1 := (calc_op1 * 10) + (ord(ch) - ord('0')) 254 | else calc_op1 := (calc_op1 * 10) - (ord(ch) - ord('0')); 255 | end; 256 | end; 257 | RADIX16: begin 258 | if ch in ['0'..'9'] then calc_op1 := (calc_op1 shl 4) or (ord(ch) - ord('0')); 259 | if ch in ['A'..'F'] then calc_op1 := (calc_op1 shl 4) or (ord(ch) - ord('A') + 10); 260 | end; 261 | end; 262 | end; 263 | end; 264 | 265 | end. 266 | -------------------------------------------------------------------------------- /SRC/DWEDOVL.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2020 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$IFDEF DEBUG} 23 | {$M 16000, 128000, 256000} 24 | {$ENDIF} 25 | {$IFNDEF DEBUG} 26 | {$M 16000, 128000, 655360} 27 | {$ENDIF} 28 | 29 | uses system2, dos, str, strutil, wincb, kminput, event, 30 | strs, unredo, dwedtype, dwedhndl, dwedutil, dwedhl, dwedscru, dwedlnch, 31 | scr, ansi; 32 | 33 | procedure edit(var ctx : TEditorContext; show_welcome_msg : boolean); 34 | var scru, prev_scru, i : integer; 35 | event : TEvent; 36 | first_time : boolean; 37 | begin 38 | Fade0; 39 | first_time := true; 40 | scru := SCRU_FULL; 41 | while scru <> SCRU_QUIT do begin 42 | if scru <> SCRU_NONE then begin 43 | dwedscru.update(ctx, scru); 44 | if show_welcome_msg then begin 45 | with ctx.current^.config^.color do begin 46 | scr.cln(0, 0, top); 47 | scr.printhl(2, 0, top, top_hl, WELCOME_MSG); 48 | end; 49 | scr.show; 50 | show_welcome_msg := false; 51 | end; 52 | scru := SCRU_NONE; 53 | if first_time then begin 54 | first_time := false; 55 | FadeIn; 56 | end; 57 | end; 58 | if not kbd_haskey then begin 59 | wait_event(event); 60 | scru := process_event(ctx, event); 61 | end else begin 62 | i := 0; 63 | prev_scru := 0; 64 | while (i < 8) and kbd_haskey do begin 65 | wait_event(event); 66 | scru := process_event(ctx, event); 67 | if prev_scru < scru then prev_scru := scru; 68 | if (scru <> SCRU_NONE) and (scru <> SCRU_FULL) then begin scru := prev_scru; break; end; 69 | inc(i); 70 | end; 71 | end; 72 | end; 73 | FadeOut; 74 | end; 75 | 76 | procedure reset_context(var ctx : TEditorContext); 77 | var f : file; 78 | path : string; 79 | i : integer; 80 | begin 81 | fillchar(ctx, sizeof(TEditorContext), #0); 82 | with ctx do begin 83 | all := nil; 84 | current := nil; 85 | ins := true; 86 | exit_code := 0; 87 | config.width := scr.getwidth; 88 | config.height := scr.getheight; 89 | config.tab_size := 8; 90 | config.hl_enable := false; 91 | config.color.top := $70; 92 | config.color.top_hl := $74; 93 | config.color.text_dl := $08; 94 | config.color.text := $07; 95 | config.color.text_hl := $03; 96 | config.color.text_sel := $17; 97 | config.color.menu := $1b; 98 | config.color.menu_sel := $30; 99 | config.color.help_menu := $07; 100 | config.color.help_menu_sel := $70; 101 | config.color.help := $07; 102 | config.color.help_hl := $03; 103 | config.udef_f5 := ''; 104 | config.udef_f8 := ''; 105 | config.udef_f9 := ''; 106 | config.memory := MEM_DOS; 107 | getmem(clipboard, CB_SIZE); 108 | clipboard[0] := #0; 109 | has_wincb := WCB_Detect; 110 | search := ''; 111 | replace := ''; 112 | help_topic_id := 0; 113 | temp := ''; 114 | end; 115 | {$IFDEF DEBUG} 116 | ctx.temp := 'TEMP.CFG'; 117 | {$ENDIF} 118 | {$IFNDEF DEBUG} 119 | ctx.temp := get_temp_name; 120 | {$ENDIF} 121 | path := ''; 122 | if length(path) = 0 then path := getenv(ENV_TEMP); 123 | if length(path) = 0 then path := getenv(ENV_TMP); 124 | if (length(path) <> 0) and (path[length(path)] <> '\') then path := path + '\'; 125 | ctx.temp := path + ctx.temp; 126 | end; 127 | 128 | procedure process_param(var ctx : TEditorContext; key, value : string); 129 | begin 130 | if length(key) = 0 then exit; 131 | if key = CFG_TAB_SIZE then ctx.config.tab_size := ahtob(value) 132 | else if key = CFG_COLOR_TOP then ctx.config.color.top := ahtob(value) 133 | else if key = CFG_COLOR_TOP_HL then ctx.config.color.top_hl := ahtob(value) 134 | else if key = CFG_COLOR_TEXT then ctx.config.color.text := ahtob(value) 135 | else if key = CFG_COLOR_TEXT_HL then ctx.config.color.text_hl := ahtob(value) 136 | else if key = CFG_COLOR_TEXT_DL then ctx.config.color.text_dl := ahtob(value) 137 | else if key = CFG_COLOR_TEXT_SEL then ctx.config.color.text_sel := ahtob(value) 138 | else if key = CFG_COLOR_MENU then ctx.config.color.menu := ahtob(value) 139 | else if key = CFG_COLOR_MENU_SEL then ctx.config.color.menu_sel := ahtob(value) 140 | else if key = CFG_COLOR_HELP_MENU then ctx.config.color.help_menu := ahtob(value) 141 | else if key = CFG_COLOR_HELP_MENU_SEL then ctx.config.color.help_menu_sel := ahtob(value) 142 | else if key = CFG_COLOR_HELP then ctx.config.color.help := ahtob(value) 143 | else if key = CFG_COLOR_HELP_HL then ctx.config.color.help_hl := ahtob(value) 144 | else if key = CFG_USR_DEF_F5 then ctx.config.udef_f5 := value 145 | else if key = CFG_USR_DEF_F8 then ctx.config.udef_f8 := value 146 | else if key = CFG_USR_DEF_F9 then ctx.config.udef_f9 := value 147 | else if key = CFG_HL_ENABLE then ctx.config.hl_enable := (ahtob(value) <> 0) 148 | else if key = CFG_MEMORY then ctx.config.memory := value 149 | else begin writelnerr('Unknown parameter ' + key + '. Press Enter...'); system.readln; end; 150 | if ctx.config.tab_size > 32 then ctx.config.tab_size := 8; 151 | end; 152 | 153 | procedure split(var param, key, value : string); 154 | var i : integer; 155 | begin 156 | key := ''; 157 | value := ''; 158 | for i := 1 to length(param) do begin 159 | if param[i] = '=' then begin 160 | key := copy(param, 1, i - 1); 161 | value := copy(param, i + 1, length(param) - i); 162 | break; 163 | end; 164 | end; 165 | if (length(key) = 0) and (length(value) = 0) then key := param; 166 | key := trim(key); 167 | upstr(key); 168 | value := trim(value); 169 | end; 170 | 171 | function has_switch(var s : string) : boolean; 172 | begin 173 | has_switch := (length(s) > 0) and (s[1] in ['-', '/']); 174 | end; 175 | 176 | procedure load_config(var ctx : TEditorContext; fname : string); 177 | var f : bfile; 178 | str : string; 179 | key, value : string; 180 | begin 181 | if not FileExists(fname) then exit; 182 | assign(f, fname); 183 | system2.reset(f); 184 | if not isopen(f) then exit; 185 | while not eof(f) do begin 186 | readln(f, str); 187 | split(str, key, value); 188 | process_param(ctx, key, value); 189 | end; 190 | close(f); 191 | end; 192 | 193 | procedure parse_temp(var ctx : TEditorContext); 194 | var f : bfile; 195 | s, ss : string; 196 | i, p : integer; 197 | errCode : integer; 198 | x, scrx, scry : integer; 199 | cline_num : longint; 200 | fname : string; 201 | begin 202 | assign(f, ctx.temp); 203 | system2.reset(f); 204 | if not isopen(f) then exit; 205 | while not eof(f) do begin 206 | readln(f, s); 207 | i := 1; 208 | p := 1; 209 | while (s[p] <> ',') and (p < length(s)) do inc(p); 210 | ss := copy(s, i, p - i); 211 | x := atoi(ss, 1); 212 | inc(p); i := p; 213 | 214 | while (s[p] <> ',') and (p < length(s)) do inc(p); 215 | ss := copy(s, i, p - i); 216 | scrx := atoi(ss, 0); 217 | inc(p); i := p; 218 | 219 | while (s[p] <> ',') and (p < length(s)) do inc(p); 220 | ss := copy(s, i, p - i); 221 | scry := atoi(ss, 0); 222 | inc(p); i := p; 223 | 224 | while (s[p] <> ',') and (p < length(s)) do inc(p); 225 | ss := copy(s, i, p - i); 226 | cline_num := atol(ss, 1); 227 | inc(p); 228 | fname := copy(s, p, length(s) - p + 1); 229 | load_file(ctx, fname, errCode, @load_file_progress); 230 | if errCode <> 0 then handle_error(ctx, errCode) else begin 231 | ctx.current^.editor.x := x; 232 | ctx.current^.scrx := scrx; 233 | ctx.current^.scry := scry; 234 | ctx.current^.cline := strs.find_num(ctx.current^.rline, cline_num); 235 | load_ed(ctx); 236 | norm_xy(ctx, 0); 237 | end; 238 | end; 239 | close(f); 240 | end; 241 | 242 | {$F+} 243 | var prevExitProc : pointer; 244 | procedure err_handler; 245 | begin 246 | spinner_stop; 247 | IF (ErrorAddr <> NIL) AND (ExitCode <> 0) THEN BEGIN 248 | scr.pop; 249 | scr.show; 250 | System.Writeln(bg(red), ' ', get_err_msg(ExitCode), ' at ' 251 | , fg(cyan), hexw(seg(pchar(errorAddr)[0])) 252 | , ':' 253 | , hexw(ofs(pchar(errorAddr)[0])) 254 | , fg(white), ' ', bg(black)); 255 | if ExitCode = 203 then begin 256 | System.Writeln(fg(green), 'Largest free block: ', maxavail, fg(white)); 257 | System.Writeln(fg(green), 'Total free memory: ', memavail, fg(white)); 258 | end; 259 | errorAddr := nil; 260 | END; 261 | exitProc := prevExitProc; 262 | strs.done; 263 | unredo.done; 264 | end; 265 | {$F-} 266 | 267 | var ctx : TEditorContext; 268 | i, pCount, errCode : integer; 269 | param, key, value : string; 270 | show_welcome_msg : boolean; 271 | pc : integer; 272 | exe_path : string; 273 | begin 274 | exe_path := getpathname(paramstr(0)); 275 | {$IFNDEF DEBUG} 276 | if not dwedlnch.is_installed then begin 277 | writelnerr(OVERLAY_MSG); 278 | halt(1); 279 | end; 280 | {$ENDIF} 281 | prevExitProc := exitProc; 282 | exitProc := @err_handler; 283 | pc := paramcount; 284 | reset_context(ctx); 285 | load_config(ctx, exe_path + CONFIG_FILE_NAME); 286 | load_config(ctx, CONFIG_FILE_NAME); 287 | for i := 1 to pc do begin 288 | param := paramstr(i); 289 | if has_switch(param) then begin 290 | System.delete(param, 1, 1); 291 | split(param, key, value); 292 | process_param(ctx, key, value); 293 | end; 294 | end; 295 | 296 | upstr(ctx.config.memory); 297 | if ctx.config.memory = MEM_SXMS then strs.init(strs.MT_SXMS) 298 | else if ctx.config.memory = MEM_SWAP then strs.init(strs.MT_SWAP) 299 | else strs.init(strs.MT_DOS); 300 | unredo.init; 301 | scr.push; 302 | scr.cls(7); 303 | if FileExists(ctx.temp) then begin 304 | show_welcome_msg := false; 305 | parse_temp(ctx); 306 | FileDelete(ctx.temp); 307 | end else begin 308 | show_welcome_msg := true; 309 | for i := 1 to pc do begin 310 | param := paramstr(i); 311 | if not has_switch(param) then begin 312 | load_file(ctx, param, errCode, @load_file_progress); 313 | if errCode <> 0 then handle_error(ctx, errCode); 314 | end; 315 | end; 316 | end; 317 | if ctx.all = nil then new_file(ctx, DEFAULT_FILE_NAME); 318 | edit(ctx, show_welcome_msg); 319 | scr.pop; 320 | scr.show; 321 | scr.set_cursor(scr.cursor); 322 | halt(ctx.exit_code); 323 | end. 324 | -------------------------------------------------------------------------------- /SRC/STRSDOS.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2022 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$A-,F-} 23 | unit strsdos; 24 | 25 | { Conventional memory string-storage } 26 | 27 | interface 28 | 29 | procedure init; 30 | procedure done; 31 | 32 | function new : pointer; 33 | 34 | procedure free(r : pointer); 35 | 36 | function create(next, prev : pointer; body : string) : pointer; 37 | 38 | function put(r : pointer; var body : string) : pointer; 39 | procedure get(r : pointer; var dest : string); 40 | function delete(r : pointer; num_from, num_to : longint) : pointer; 41 | function merge(r : pointer) : pointer; 42 | 43 | function is_first(r : pointer) : boolean; 44 | function is_last(r : pointer) : boolean; 45 | 46 | function go_first(r : pointer) : pointer; 47 | function go_last(r : pointer) : pointer; 48 | 49 | function go_prev(r : pointer) : pointer; 50 | function go_next(r : pointer) : pointer; 51 | 52 | function is_nil(r : pointer) : boolean; 53 | 54 | function renum(r : pointer) : longint; 55 | function get_num(r : pointer) : longint; 56 | function append(r : pointer; var pos : integer; p : pchar; var lnum:word) : pointer; 57 | function split(r : pointer; pos : integer) : pointer; 58 | 59 | function from_file(fname : string; tab_size : integer; var errCode : integer; scrupdate : pointer) : pointer; 60 | procedure to_file(fname : string; r : pointer; var errCode : integer; scrupdate : pointer); 61 | 62 | implementation 63 | 64 | uses System2, scr, str, strutil, dwedtype, dwedutil; 65 | 66 | type 67 | PDosStringRec = ^TDosStringRec; 68 | TDosStringRec = record 69 | next : PDosStringRec; 70 | prev : PDosStringRec; 71 | allocated : word; 72 | num : longint; 73 | len : byte; 74 | body : array[1..1] of char; 75 | end; 76 | 77 | {$F-} 78 | 79 | function norm_len(len : word) : word; 80 | var w : word; 81 | begin 82 | w := len shr 3; 83 | if (len and $07) <> 0 then inc(w); 84 | w := w shl 3; 85 | norm_len := w; 86 | end; 87 | 88 | function create(next, prev : pointer; body : string) : pointer; 89 | var len, nlen : word; 90 | r : PDosStringRec; 91 | begin 92 | len := length(body); 93 | nlen := norm_len(len); 94 | getmem(r, sizeof(TDosStringRec) + nlen - 1); 95 | r^.next := PDosStringRec(next); 96 | r^.prev := PDosStringRec(prev); 97 | r^.len := len; 98 | r^.allocated := nlen; 99 | move(body[1], r^.body[1], len); 100 | if prev <> nil then PDosStringRec(prev)^.next := r; 101 | if next <> nil then PDosStringRec(next)^.prev := r; 102 | create := r; 103 | end; 104 | 105 | procedure free_str(r : pointer); 106 | begin 107 | if r = nil then exit; 108 | freemem(r, sizeof(TDosStringRec) + PDosStringRec(r)^.allocated - 1); 109 | end; 110 | 111 | function put(r : pointer; var body : string) : pointer; 112 | var len : word; 113 | old : PDosStringRec; 114 | begin 115 | len := norm_len(length(body)); 116 | if len = PDosStringRec(r)^.allocated then begin 117 | len := length(body); 118 | move(body[1], PDosStringRec(r)^.body[1], len); 119 | PDosStringRec(r)^.len := len; 120 | end else begin 121 | old := r; 122 | r := PDosStringRec(create(PDosStringRec(r)^.next, PDosStringRec(r)^.prev, body)); 123 | PDosStringRec(r)^.num := old^.num; 124 | strsdos.free_str(old); 125 | end; 126 | put := r; 127 | end; 128 | 129 | function new : pointer; 130 | begin 131 | new := create(nil, nil, ''); 132 | end; 133 | 134 | procedure get(r : pointer; var dest : string); 135 | begin 136 | if r <> nil then begin 137 | move(PDosStringRec(r)^.body[1], dest[1], PDosStringRec(r)^.len); 138 | dest[0] := chr(PDosStringRec(r)^.len); 139 | end else dest := ''; 140 | end; 141 | 142 | function is_first(r : pointer) : boolean; 143 | begin 144 | is_first := PDosStringRec(r)^.prev = nil; 145 | end; 146 | 147 | function is_last(r : pointer) : boolean; 148 | begin 149 | is_last := PDosStringRec(r)^.next = nil; 150 | end; 151 | 152 | function go_first(r : pointer) : pointer; 153 | begin 154 | if r <> nil then begin 155 | while PDosStringRec(r)^.prev <> nil do r := PDosStringRec(r)^.prev; 156 | end; 157 | go_first := r; 158 | end; 159 | 160 | function go_last(r : pointer) : pointer; 161 | begin 162 | if r <> nil then begin 163 | while PDosStringRec(r)^.next <> nil do r := PDosStringRec(r)^.next; 164 | end; 165 | go_last := r; 166 | end; 167 | 168 | function go_prev(r : pointer) : pointer; 169 | begin 170 | if r <> nil then r := PDosStringRec(r)^.prev; 171 | go_prev := r; 172 | end; 173 | 174 | function go_next(r : pointer) : pointer; 175 | begin 176 | if r <> nil then r := PDosStringRec(r)^.next; 177 | go_next := r; 178 | end; 179 | 180 | procedure free(r : pointer); 181 | var o : pointer; 182 | begin 183 | while r <> nil do begin 184 | o := PDosStringRec(r)^.next; 185 | strsdos.free_str(r); 186 | r := o; 187 | end; 188 | end; 189 | 190 | function renum(r : pointer) : longint; 191 | var res : longint; 192 | begin 193 | res := 0; 194 | while r <> nil do begin 195 | inc(res); 196 | PDosStringRec(r)^.num := res; 197 | r := PDosStringRec(r)^.next; 198 | end; 199 | renum := res; 200 | end; 201 | 202 | function get_num(r : pointer) : longint; 203 | begin 204 | get_num := PDosStringRec(r)^.num; 205 | end; 206 | 207 | function del_str(r : PDosStringRec) : PDosStringRec; 208 | var t : PDosStringRec; 209 | begin 210 | if r <> nil then begin 211 | t := r; 212 | r := r^.next; 213 | with t^ do begin 214 | if next <> nil then next^.prev := prev; 215 | if prev <> nil then prev^.next := next; 216 | end; 217 | free_str(t); 218 | end; 219 | del_str := r; 220 | end; 221 | 222 | function delete(r : pointer; num_from, num_to : longint) : pointer; 223 | var t : PDosStringRec; 224 | n : longint; 225 | begin 226 | t := r; 227 | n := 1; 228 | while (t <> nil) and (t^.num <> num_from) do begin 229 | if t^.prev = nil then r := t; 230 | t^.num := n; inc(n); 231 | t := t^.next; 232 | end; 233 | while (t <> nil) and (t^.num <= num_to) do begin 234 | t := del_str(t); 235 | if t^.prev = nil then r := t; 236 | end; 237 | while (t <> nil) do begin 238 | t^.num := n; inc(n); 239 | t := t^.next; 240 | end; 241 | delete := r; 242 | end; 243 | 244 | function merge(r : pointer) : pointer; 245 | var s1, s2 : string; 246 | t1, t2 :PDosStringRec; 247 | begin 248 | if PDosStringRec(r)^.next <> nil then begin 249 | t1 := r; 250 | t2 := t1^.next; 251 | strsdos.get(t1, s1); 252 | strsdos.get(t2, s2); 253 | if length(s1) + length(s2) <= 255 then begin 254 | r := strsdos.create(t2^.next, t1^.prev, s1 + s2); 255 | free_str(t1); 256 | free_str(t2); 257 | end; 258 | end; 259 | merge := r; 260 | end; 261 | 262 | function append(r : pointer; var pos : integer; p : pchar; var lnum:word) : pointer; 263 | var s, src, s1, s2 : string; 264 | c : char; 265 | len : integer; 266 | begin 267 | lnum := 0; 268 | if not ((r = nil) or (p = nil)) then begin 269 | s := ''; 270 | strsdos.get(r, src); 271 | while p^ <> #0 do begin 272 | c := p^; 273 | case c of 274 | #$0A: begin 275 | inc(lnum); 276 | s1 := ''; 277 | s2 := ''; 278 | len := length(src); 279 | if len > 0 then s1 := copy(src, 1, pos - 1); 280 | if pos <= len then s2 := copy(src, pos, len - pos + 1); 281 | s1 := s1 + s; 282 | r := strsdos.put(r, s1); 283 | r := strsdos.create(PDosStringRec(r)^.next, r, s2); 284 | src := s2; 285 | pos := 1; 286 | s := ''; 287 | end; 288 | else if c <> #$0d then s := s + c; 289 | end; 290 | inc(p); 291 | end; 292 | if length(s) <> 0 then begin 293 | strsdos.get(r, s1); 294 | System.insert(s, s1, pos); 295 | inc(pos, length(s)); 296 | r := strsdos.put(r, s1); 297 | end; 298 | end; 299 | append := r; 300 | end; 301 | 302 | function split(r : pointer; pos : integer) : pointer; 303 | var s1, s2 : string; 304 | begin 305 | strsdos.get(r, s1); 306 | s2 := copy(s1, pos, length(s1) - pos + 1); 307 | s1 := rtrim(copy(s1, 1, pos - 1)); 308 | r := strsdos.put(r, s1); 309 | strsdos.create(PDosStringRec(r)^.next, r, s2); 310 | split := r; 311 | end; 312 | 313 | function from_file(fname : string; tab_size : integer; var errCode : integer; scrupdate : pointer) : pointer; 314 | var root, cur, last : Pointer; 315 | f : bfile; 316 | s : string; 317 | i : integer; 318 | total : longint; 319 | position : longint; 320 | scrup : TPercentUpdateProc; 321 | tabs : string; 322 | readed : integer; 323 | start_date : longint; 324 | begin 325 | scrup := TPercentUpdateProc(scrupdate); 326 | start_date := get_ticks; 327 | 328 | fillchar(f, sizeof(bfile), #0); 329 | fillchar(tabs[1], 255, #32); 330 | tabs[0] := chr(tab_size); 331 | 332 | root := nil; last := nil; 333 | readed := 0; 334 | total := 0; 335 | position := 0; 336 | 337 | assign(f, fname); 338 | reset(f); 339 | if not IsOpen(f) then errCode := 104 else total := filesize(f); 340 | 341 | if total <> 0 then begin 342 | while not eof(f) do begin 343 | readln(f, s); 344 | remove_tabs(s, tabs); 345 | cur := strsdos.create(nil, last, s); 346 | if root = nil then root := cur; 347 | last := cur; 348 | inc(readed, ord(s[0])); 349 | if readed > PROGRESS_UPDATE then begin 350 | if scrupdate <> nil then begin 351 | position := filepos(f); 352 | scrup(position, total, start_date); 353 | end; 354 | readed := 0; 355 | end; 356 | end; 357 | end; 358 | 359 | if IsOpen(f) then close(f); 360 | 361 | if root = nil then root := strsdos.new; 362 | from_file := root; 363 | end; 364 | 365 | procedure to_file(fname : string; r : pointer; var errCode : integer; scrupdate : pointer); 366 | var f : bfile; 367 | s : string; 368 | total : longint; 369 | position : longint; 370 | scrup : TPercentUpdateProc; 371 | writed : integer; 372 | start_date : longint; 373 | begin 374 | assign(f, fname); 375 | rewrite(f); 376 | if not isopen(f) then begin 377 | errCode := 105; 378 | exit; 379 | end; 380 | scrup := TPercentUpdateProc(scrupdate); 381 | start_date := get_ticks; 382 | 383 | total := renum(r); 384 | position := 0; 385 | writed := 0; 386 | 387 | while r <> nil do begin 388 | strsdos.get(r, s); 389 | writeln(f, s); 390 | r := strsdos.go_next(r); 391 | 392 | inc(writed, ord(s[0])); 393 | if writed > PROGRESS_UPDATE then begin 394 | if scrupdate <> nil then begin 395 | inc(position); 396 | scrup(position, total, start_date); 397 | end; 398 | writed := 0; 399 | end; 400 | end; 401 | truncate(f); 402 | close(f); 403 | end; 404 | 405 | procedure init; 406 | begin 407 | end; 408 | 409 | procedure done; 410 | begin 411 | end; 412 | 413 | function is_nil(r : pointer) : boolean; 414 | begin 415 | is_nil := r = nil; 416 | end; 417 | 418 | end. 419 | -------------------------------------------------------------------------------- /SRC/SCR.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2020 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$F+} 23 | unit scr; 24 | 25 | interface 26 | 27 | var 28 | screen : pchar; 29 | cursor : word; 30 | 31 | procedure cls(clr : byte); 32 | procedure cln(x, y : integer; clr : byte); 33 | procedure print(x, y : integer; clr : byte; s : string); 34 | procedure printhl(x, y : integer; clr, hlclr : byte; s : string); 35 | procedure hprint(x, y:integer; clr : byte; c : char; len : integer); 36 | procedure vprint(x, y:integer; clr : byte; c : char; len : integer); 37 | procedure chcolor(x, y:integer; clr : byte; len: integer); 38 | 39 | procedure push; 40 | procedure pop; 41 | procedure pick; 42 | procedure show; 43 | 44 | procedure locate(x, y:integer); 45 | 46 | procedure cursor_off; 47 | procedure cursor_on; 48 | procedure cursor_big; 49 | 50 | function get_cursor:word; 51 | procedure set_cursor(w : word); 52 | 53 | procedure set_blink(on : boolean); 54 | 55 | function getwidth:integer; 56 | function getheight:integer; 57 | 58 | function getx:integer; 59 | function gety:integer; 60 | 61 | procedure scroll_up(stx, sty, w, h, lines : integer); 62 | procedure scroll_down(stx, sty, w, h, lines : integer); 63 | 64 | procedure spinner_start; 65 | procedure spinner_stop; 66 | 67 | procedure Fade0; 68 | procedure FadeIn; 69 | procedure FadeOut; 70 | 71 | procedure reset_palette; 72 | procedure gray_palette; 73 | 74 | procedure WaitRetrace; 75 | 76 | implementation 77 | 78 | uses kminput, dos, detect; 79 | 80 | const vseg : word = 0; 81 | SPINNER : string[8] = '|/-\|/-\'; 82 | 83 | type 84 | 85 | PScr=^TScr; 86 | TScr=record 87 | prev : PScr; 88 | size : word; 89 | x, y : integer; 90 | buf : byte; 91 | end; 92 | 93 | const 94 | last_scr_buf : PScr = nil; 95 | FADE_STEP = 8; 96 | FADE_DELAY = 15; 97 | 98 | var 99 | screen_size, line_size : word; 100 | 101 | spinnerValue : word; 102 | spinnerOldInt : pointer; 103 | spinnerOn : boolean; 104 | 105 | palette : array[0..(256 * 3)] of byte; 106 | vga : boolean; 107 | 108 | function getheight : integer;assembler; 109 | asm 110 | push ds 111 | mov ax, seg0040 112 | mov ds, ax 113 | mov al, byte ptr[$0084] 114 | xor ah, ah 115 | inc ax 116 | pop ds 117 | end; 118 | 119 | function getwidth : integer;assembler; 120 | asm 121 | push ds 122 | mov ax, seg0040 123 | mov ds, ax 124 | mov ax, word ptr[$004a] 125 | pop ds 126 | end; 127 | 128 | { in: ax = x, cx = y } 129 | { out: es:di } 130 | procedure buf_es_di;assembler; 131 | asm 132 | mov bx, ax 133 | mov ax, line_size 134 | mul cx 135 | xchg bx, ax 136 | shl ax, 1 137 | add ax, bx 138 | les di, screen 139 | add di, ax 140 | end; 141 | 142 | procedure cls(clr : byte);assembler; 143 | asm 144 | push es 145 | 146 | mov ax, screen_size 147 | shr ax, 1 148 | xchg ax, cx 149 | mov ah, clr 150 | mov al, ' ' 151 | les di, screen 152 | cld 153 | repz stosw 154 | 155 | pop es 156 | end; 157 | 158 | procedure cln(x, y : integer; clr : byte);assembler; 159 | asm 160 | push es 161 | 162 | call getwidth 163 | push ax 164 | mov ax, x 165 | mov cx, y 166 | call buf_es_di 167 | pop cx 168 | sub cx, x 169 | mov ah, clr 170 | mov al, ' ' 171 | cld 172 | repz stosw 173 | 174 | pop es 175 | end; 176 | 177 | procedure hprint(x, y : integer; clr : byte; c : char; len : integer);assembler; 178 | asm 179 | push es 180 | mov ax, x 181 | mov cx, y 182 | call buf_es_di 183 | xor ch, ch 184 | mov cx, len 185 | xor ch, ch 186 | mov ah, clr 187 | mov al, c 188 | cld 189 | repz stosw 190 | pop es 191 | end; 192 | 193 | procedure chcolor(x, y : integer; clr : byte; len : integer);assembler; 194 | asm 195 | push es 196 | mov ax, x 197 | mov cx, y 198 | call buf_es_di 199 | inc di 200 | mov cx, len 201 | mov al, clr 202 | cld 203 | or cl, cl 204 | jz @end 205 | @cont: 206 | stosb 207 | inc di 208 | dec cl 209 | jnz @cont 210 | @end: 211 | pop es 212 | end; 213 | 214 | procedure vprint(x, y : integer; clr : byte; c : char; len : integer);assembler; 215 | asm 216 | push es 217 | mov ax, x 218 | mov cx, y 219 | call buf_es_di 220 | mov bx, line_size 221 | sub bx, 2 222 | mov cx, len 223 | mov ah, clr 224 | mov al, c 225 | cld 226 | or cl, cl 227 | jz @end 228 | @cont: 229 | stosw 230 | add di, bx 231 | dec cl 232 | jnz @cont 233 | @end: 234 | pop es 235 | end; 236 | 237 | procedure print(x, y:integer; clr : byte; s : string);assembler; 238 | asm 239 | push es 240 | push ds 241 | 242 | mov ax, x 243 | mov cx, y 244 | call buf_es_di 245 | mov ah, clr 246 | lds si, s 247 | lodsb 248 | or al, al 249 | jz @end 250 | mov cl, al 251 | cld 252 | @cont: 253 | lodsb 254 | stosw 255 | dec cl 256 | jnz @cont 257 | @end: 258 | pop ds 259 | pop es 260 | end; 261 | 262 | procedure printhl(x, y : integer; clr, hlclr : byte; s : string);assembler; 263 | asm 264 | push es 265 | push ds 266 | 267 | mov ax, x 268 | mov cx, y 269 | call buf_es_di 270 | 271 | mov ah, clr 272 | mov bh, hlclr 273 | lds si, s 274 | lodsb 275 | or al, al 276 | jz @end 277 | mov cl, al 278 | cld 279 | @cont: 280 | lodsb 281 | cmp al, '~' 282 | jnz @print 283 | xchg ah, bh 284 | jmp @cont2 285 | @print: 286 | stosw 287 | @cont2: 288 | dec cl 289 | jnz @cont 290 | @end: 291 | pop ds 292 | pop es 293 | end; 294 | 295 | procedure show;assembler; 296 | asm 297 | call mouse_hide 298 | call WaitRetrace 299 | push es 300 | push ds 301 | 302 | 303 | mov ax, screen_size 304 | shr ax, 1 305 | mov cx, ax 306 | mov ax, vseg 307 | mov es, ax 308 | lds si, screen 309 | xor di, di 310 | cld 311 | repz movsw 312 | 313 | pop ds 314 | pop es 315 | 316 | call mouse_show 317 | end; 318 | 319 | procedure locate(x, y : integer);assembler; 320 | asm 321 | push ds 322 | mov ax, word ptr [seg0040] 323 | mov ds, ax 324 | mov bh, byte ptr [$0062] 325 | pop ds 326 | 327 | mov dl, byte ptr [x] 328 | mov dh, byte ptr [y] 329 | mov ah, 2 330 | int $10 331 | end; 332 | 333 | function getx : integer;assembler; 334 | asm 335 | push ds 336 | mov ax, word ptr [seg0040] 337 | mov ds, ax 338 | mov bh, byte ptr [$0062] 339 | pop ds 340 | 341 | mov ah, 3 342 | int $10 343 | mov al,dl 344 | xor ah,ah 345 | end; 346 | 347 | function gety : integer;assembler; 348 | asm 349 | push ds 350 | mov ax, word ptr [seg0040] 351 | mov ds, ax 352 | mov bh, byte ptr [$0062] 353 | pop ds 354 | 355 | mov ah, 3 356 | int $10 357 | mov al,dh 358 | xor ah,ah 359 | end; 360 | 361 | procedure push; 362 | var p : PScr; 363 | begin 364 | getmem(p, screen_size + sizeof(TScr) - 1); 365 | p^.size := screen_size; 366 | p^.prev := last_scr_buf; 367 | p^.x := getx; 368 | p^.y := gety; 369 | move(screen^, p^.buf, p^.size); 370 | last_scr_buf := p; 371 | end; 372 | 373 | procedure pop; 374 | var p : PScr; 375 | begin 376 | if last_scr_buf = nil then exit; 377 | WaitRetrace; 378 | move(last_scr_buf^.buf, screen^, last_scr_buf^.size); 379 | p := last_scr_buf; 380 | last_scr_buf := last_scr_buf^.prev; 381 | scr.locate(p^.x, p^.y); 382 | freemem(p, p^.size + sizeof(TScr) - 1); 383 | end; 384 | 385 | procedure pick; 386 | begin 387 | if last_scr_buf = nil then exit; 388 | WaitRetrace; 389 | move(last_scr_buf^.buf, screen^, last_scr_buf^.size); 390 | scr.locate(last_scr_buf^.x, last_scr_buf^.y); 391 | end; 392 | 393 | procedure set_cursor(w : word);assembler; 394 | asm 395 | mov cx, w 396 | mov ah, 1 397 | int $10 398 | end; 399 | 400 | function get_cursor : word;assembler; 401 | asm 402 | mov ah, $0f 403 | int $10 404 | mov ah, 3 405 | int $10 406 | mov ax, cx 407 | end; 408 | 409 | 410 | procedure cursor_off; 411 | begin 412 | set_cursor($2020); 413 | end; 414 | 415 | procedure cursor_on; 416 | begin 417 | set_cursor(cursor); 418 | end; 419 | 420 | procedure cursor_big; 421 | begin 422 | set_cursor(cursor and $FF); 423 | end; 424 | 425 | procedure set_blink(on : boolean);assembler; 426 | asm 427 | mov bl, byte ptr [on] 428 | mov ax, $1003 429 | int $10 430 | end; 431 | 432 | procedure scroll_up(stx, sty, w, h, lines : integer); 433 | var i : integer; 434 | scrw : integer; 435 | slines : integer; 436 | cur : integer; 437 | begin 438 | i := 0; w := w shl 1; scrw := getwidth; 439 | slines := (lines * scrw) shl 1; 440 | cur := (stx + (sty * scrw)) shl 1; 441 | scrw := scrw shl 1; 442 | WaitRetrace; 443 | while i < (h - lines) do begin 444 | move(screen[slines + cur], screen[cur], w); 445 | inc(cur, scrw); 446 | inc(i); 447 | end; 448 | end; 449 | 450 | procedure scroll_down(stx, sty, w, h, lines : integer); 451 | var i : integer; 452 | scrw : integer; 453 | slines : integer; 454 | cur : integer; 455 | begin 456 | i := h - lines; w := w shl 1; scrw := getwidth; 457 | slines := (lines * scrw) shl 1; 458 | cur := (stx + i * scrw) shl 1; 459 | scrw := scrw shl 1; 460 | WaitRetrace; 461 | while i >= 0 do begin 462 | move(screen[cur], screen[slines + cur], w); 463 | dec(cur, scrw); 464 | dec(i); 465 | end; 466 | end; 467 | 468 | procedure spinner1c;interrupt; 469 | var spin : char; 470 | begin 471 | spin := SPINNER[((spinnerValue shr 3) mod length(SPINNER)) + 1]; 472 | mem[vseg:0] := Ord(spin); 473 | mem[vseg:1] := $20; 474 | screen^ := spin; 475 | screen[1] := #$20; 476 | Inc(spinnerValue); 477 | if spinnerValue = 90 then gray_palette; 478 | end; 479 | 480 | procedure spinner_start; 481 | begin 482 | if spinnerOn then exit; 483 | spinnerValue := 0; 484 | SetIntVec($1c, @spinner1c); 485 | spinnerOn := true; 486 | end; 487 | 488 | procedure spinner_stop; 489 | begin 490 | SetIntVec($1c, spinnerOldInt); 491 | reset_palette; 492 | spinnerOn := false; 493 | end; 494 | 495 | procedure delay(ms : word); assembler; 496 | asm 497 | mov ax, 1000 498 | mul ms 499 | mov cx, dx 500 | mov dx, ax 501 | mov ah, $86 502 | int $15 503 | end; 504 | 505 | procedure save_palette; 506 | var i : integer; 507 | begin 508 | if not vga then exit; 509 | for i := 0 to 255 do begin 510 | Port[$3C7] := i; 511 | Palette[i * 3] := Port[$3C9]; 512 | Palette[i * 3 + 1] := Port[$3C9]; 513 | Palette[i * 3 + 2] := Port[$3C9]; 514 | end; 515 | end; 516 | 517 | procedure set_color(num, r, g, b : byte); 518 | begin 519 | Port[$3C8] := num; 520 | Port[$3C9] := r; 521 | Port[$3C9] := g; 522 | Port[$3C9] := b; 523 | end; 524 | 525 | procedure reset_palette; 526 | var i : integer; 527 | begin 528 | if not vga then exit; 529 | for i := 0 to 255 do begin 530 | set_color(i, palette[i * 3], palette[i * 3 + 1], palette[i * 3 + 2]); 531 | end; 532 | end; 533 | 534 | procedure gray_palette; 535 | var i, n : integer; 536 | begin 537 | if not vga then exit; 538 | for i := 0 to 255 do begin 539 | n := palette[i * 3] + palette[i * 3 + 1] + palette[i * 3 + 2]; 540 | n := n div 6; 541 | set_color(i, n, n, n); 542 | end; 543 | end; 544 | 545 | procedure Fade0; 546 | var i : integer; 547 | begin 548 | if not vga then exit; 549 | WaitRetrace; 550 | for i := 0 to 255 do begin 551 | set_color(i, 0, 0, 0); 552 | end; 553 | end; 554 | 555 | procedure FadeIn; 556 | var op1, op2, op3 : byte; 557 | p1, p2, p3 : byte; 558 | i, j : integer; 559 | begin 560 | if not vga then exit; 561 | Fade0; 562 | for j := 0 to 7 do begin 563 | WaitRetrace; 564 | for i := 0 to 255 do begin 565 | Port[$3C7] := i; 566 | op1 := Port[$3C9]; 567 | op2 := Port[$3C9]; 568 | op3 := Port[$3C9]; 569 | p1 := palette[i * 3]; 570 | p2 := palette[i * 3 + 1]; 571 | p3 := palette[i * 3 + 2]; 572 | if op1 + FADE_STEP <= p1 then Inc(op1, FADE_STEP) else op1 := p1; 573 | if op2 + FADE_STEP <= p2 then Inc(op2, FADE_STEP) else op2 := p2; 574 | if op3 + FADE_STEP <= p3 then Inc(op3, FADE_STEP) else op3 := p3; 575 | set_color(i, op1, op2, op3); 576 | end; 577 | delay(FADE_DELAY); 578 | end; 579 | end; 580 | 581 | 582 | procedure FadeOut; 583 | var op1, op2, op3 : byte; 584 | i, j : integer; 585 | begin 586 | if not vga then exit; 587 | for j := 0 to 7 do begin 588 | WaitRetrace; 589 | for i := 0 to 255 do begin 590 | Port[$3C7] := i; 591 | op1 := Port[$3C9]; 592 | op2 := Port[$3C9]; 593 | op3 := Port[$3C9]; 594 | if op1 >= FADE_STEP then Dec(op1, FADE_STEP) else op1 := 0; 595 | if op2 >= FADE_STEP then Dec(op2, FADE_STEP) else op2 := 0; 596 | if op3 >= FADE_STEP then Dec(op3, FADE_STEP) else op3 := 0; 597 | set_color(i, op1, op2, op3); 598 | end; 599 | delay(FADE_DELAY); 600 | end; 601 | reset_palette; 602 | end; 603 | 604 | procedure WaitRetrace; assembler; 605 | asm 606 | mov dx, $3da 607 | @l1: in al, dx 608 | test al, 8 609 | jnz @l1 610 | @l2: in al, dx 611 | test al, 8 612 | jz @l2 613 | end; 614 | 615 | begin 616 | GetIntVec($1c, spinnerOldInt); 617 | spinnerOn := false; 618 | vga := Detect.IsVga; 619 | save_palette; 620 | cursor := scr.get_cursor; 621 | if (not vga) and IsMonochrome then vseg := segb000 else vseg := segb800; 622 | scr.set_blink(false); 623 | screen_size := (scr.getwidth * scr.getheight) shl 1; 624 | line_size := scr.getwidth shl 1; 625 | getmem(screen, screen_size); 626 | move(mem[vseg:0], screen^, screen_size); 627 | mouse_show; 628 | end. 629 | -------------------------------------------------------------------------------- /SRC/STRSSWAP.PAS: -------------------------------------------------------------------------------- 1 | { MIT License 2 | 3 | Copyright (c) 2022 Viacheslav Komenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. } 22 | {$A-,F-} 23 | unit strsswap; 24 | 25 | { External memory string-storage } 26 | 27 | interface 28 | 29 | uses dwedtype; 30 | 31 | procedure init; 32 | procedure done; 33 | 34 | function new : dword; 35 | procedure free(r : dword); 36 | 37 | function create(next, prev : dword; body : string) : dword; 38 | 39 | function put(r : dword; var body : string) : dword; 40 | procedure get(r : dword; var dest : string); 41 | function delete(r : dword; num_from, num_to : dword) : dword; 42 | function merge(r : dword) : dword; 43 | 44 | function is_first(r : dword) : boolean; 45 | function is_last(r : dword) : boolean; 46 | 47 | function go_first(r : dword) : dword; 48 | function go_last(r : dword) : dword; 49 | 50 | function go_prev(r : dword) : dword; 51 | function go_next(r : dword) : dword; 52 | 53 | function is_nil(r : dword) : boolean; 54 | 55 | function renum(r : dword) : dword; 56 | function get_num(r : dword) : dword; 57 | function append(r : dword; var pos : integer; p : pchar; var lnum:word) : dword; 58 | function split(r : dword; pos : integer) : dword; 59 | 60 | function from_file(fname : string; tab_size : integer; var errCode : integer; scrupdate : pointer) : dword; 61 | procedure to_file(fname : string; r : dword; var errCode : integer; scrupdate : pointer); 62 | 63 | implementation 64 | 65 | uses System2, scr, str, dbm, dbb, strutil, dwedutil; 66 | 67 | type 68 | TExtStringRec = record 69 | next : dword; 70 | prev : dword; 71 | len : word; 72 | num : dword; 73 | recno : dword; 74 | end; 75 | 76 | const 77 | MEM_BLK_SIZE = 32; 78 | IDX_BLK_SIZE = sizeof(TExtStringRec); 79 | 80 | var dbm_mem : DBMFile; 81 | dbb_idx : DBBFile; 82 | 83 | {$F-} 84 | 85 | function create(next, prev : dword; body : string) : dword; 86 | var r : dword; 87 | rec : TExtStringRec; 88 | begin 89 | FillChar(rec, SizeOf(TExtStringRec), #0); 90 | rec.next := next; 91 | rec.prev := prev; 92 | rec.len := length(body) + 1; 93 | if rec.len <> 1 then rec.recno := dbm_add(dbm_mem, body, rec.len); 94 | r := dbb_add(dbb_idx, rec); 95 | if prev <> 0 then begin 96 | dbb_get(dbb_idx, prev, rec); 97 | rec.next := r; 98 | dbb_put(dbb_idx, prev, rec); 99 | end; 100 | if next <> 0 then begin 101 | dbb_get(dbb_idx, next, rec); 102 | rec.prev := r; 103 | dbb_put(dbb_idx, next, rec); 104 | end; 105 | create := r; 106 | end; 107 | 108 | procedure free_str(r : dword); 109 | var rec : TExtStringRec; 110 | begin 111 | if r = 0 then exit; 112 | dbb_get(dbb_idx, r, rec); 113 | dbm_free(dbm_mem, rec.recno); 114 | dbb_free(dbb_idx, r); 115 | end; 116 | 117 | function put(r : dword; var body : string) : dword; 118 | var rec : TExtStringRec; 119 | begin 120 | if r <> 0 then begin 121 | dbb_get(dbb_idx, r, rec); 122 | dbm_free(dbm_mem, rec.recno); 123 | rec.len := length(body) + 1; 124 | if rec.len = 1 then begin 125 | rec.recno := 0; 126 | end else begin 127 | rec.recno := dbm_add(dbm_mem, body, rec.len) 128 | end; 129 | dbb_put(dbb_idx, r, rec); 130 | end; 131 | put := r; 132 | end; 133 | 134 | function new : dword; 135 | begin 136 | new := create(0, 0, ''); 137 | end; 138 | 139 | procedure get(r : dword; var dest : string); 140 | var rec : TExtStringRec; 141 | begin 142 | dest[0] := #0; 143 | if r <> 0 then begin 144 | dbb_get(dbb_idx, r, rec); 145 | if rec.recno <> 0 then dbm_get(dbm_mem, rec.recno, dest, rec.len); 146 | end; 147 | end; 148 | 149 | function is_first(r : dword) : boolean; 150 | var rec : TExtStringRec; 151 | begin 152 | dbb_get(dbb_idx, r, rec); 153 | is_first := rec.prev = 0; 154 | end; 155 | 156 | function is_last(r : dword) : boolean; 157 | var rec : TExtStringRec; 158 | begin 159 | dbb_get(dbb_idx, r, rec); 160 | is_last := rec.next = 0; 161 | end; 162 | 163 | function go_first(r : dword) : dword; 164 | var rec : TExtStringRec; 165 | begin 166 | if r <> 0 then begin 167 | dbb_get(dbb_idx, r, rec); 168 | while rec.prev <> 0 do begin 169 | r := rec.prev; 170 | dbb_get(dbb_idx, r, rec); 171 | end; 172 | end; 173 | go_first := r; 174 | end; 175 | 176 | function go_last(r : dword) : dword; 177 | var rec : TExtStringRec; 178 | begin 179 | if r <> 0 then begin 180 | dbb_get(dbb_idx, r, rec); 181 | while rec.next <> 0 do begin 182 | r := rec.next; 183 | dbb_get(dbb_idx, r, rec); 184 | end; 185 | end; 186 | go_last := r; 187 | end; 188 | 189 | function go_prev(r : dword) : dword; 190 | var rec : TExtStringRec; 191 | begin 192 | if r <> 0 then begin 193 | dbb_get(dbb_idx, r, rec); 194 | r := rec.prev; 195 | end; 196 | go_prev := r; 197 | end; 198 | 199 | function go_next(r : dword) : dword; 200 | var rec : TExtStringRec; 201 | begin 202 | if r <> 0 then begin 203 | dbb_get(dbb_idx, r, rec); 204 | r := rec.next; 205 | end; 206 | go_next := r; 207 | end; 208 | 209 | procedure free(r : dword); 210 | var rec : TExtStringRec; 211 | begin 212 | while r <> 0 do begin 213 | dbb_get(dbb_idx, r, rec); 214 | dbb_free(dbb_idx, r); 215 | dbm_free(dbm_mem, rec.recno); 216 | r := rec.next; 217 | end; 218 | end; 219 | 220 | function renum(r : dword) : dword; 221 | var rec : TExtStringRec; 222 | res : dword; 223 | begin 224 | res := 0; 225 | while r <> 0 do begin 226 | inc(res); 227 | dbb_get(dbb_idx, r, rec); 228 | rec.num := res; 229 | dbb_put(dbb_idx, r, rec); 230 | r := rec.next; 231 | end; 232 | renum := res; 233 | end; 234 | 235 | function get_num(r : dword) : dword; 236 | var rec : TExtStringRec; 237 | begin 238 | dbb_get(dbb_idx, r, rec); 239 | get_num := rec.num; 240 | end; 241 | 242 | function delete(r : dword; num_from, num_to : dword) : dword; 243 | var rno, lrno : dword; 244 | line, lline : dword; 245 | rec : TExtStringRec; 246 | begin 247 | rno := r; 248 | line := 1; 249 | lrno := 0; 250 | while (rno <> 0) and (line < num_from) do begin 251 | lrno := rno; 252 | dbb_get(dbb_idx, rno, rec); 253 | rno := rec.next; 254 | inc(line); 255 | end; 256 | lline := line; 257 | while (rno <> 0) and (line <= num_to) do begin 258 | dbb_get(dbb_idx, rno, rec); 259 | dbm_free(dbm_mem, rec.recno); 260 | dbb_free(dbb_idx, rno); 261 | rno := rec.next; 262 | inc(line); 263 | end; 264 | if lrno = 0 then r := rno; 265 | if lrno <> 0 then begin 266 | dbb_get(dbb_idx, lrno, rec); 267 | rec.next := rno; 268 | dbb_put(dbb_idx, lrno, rec); 269 | end; 270 | if rno <> 0 then begin 271 | dbb_get(dbb_idx, rno, rec); 272 | rec.prev := lrno; 273 | dbb_put(dbb_idx, rno, rec); 274 | end; 275 | line := lline; 276 | while rno <> 0 do begin 277 | dbb_get(dbb_idx, rno, rec); 278 | rec.num := line; 279 | dbb_put(dbb_idx, rno, rec); 280 | inc(line); 281 | rno := rec.next; 282 | end; 283 | delete := r; 284 | end; 285 | 286 | function merge(r : dword) : dword; 287 | var s1, s2 : string; 288 | t1, t2 : TExtStringRec; 289 | r1, r2 : dword; 290 | begin 291 | r1 := r; 292 | dbb_get(dbb_idx, r1, t1); 293 | r2 := t1.next; 294 | if r2 <> 0 then begin 295 | s1 := ''; 296 | s2 := ''; 297 | dbb_get(dbb_idx, r2, t2); 298 | if t1.recno <> 0 then dbm_get(dbm_mem, t1.recno, s1, t1.len); 299 | if t2.recno <> 0 then dbm_get(dbm_mem, t2.recno, s2, t2.len); 300 | if length(s1) + length(s2) <= 255 then begin 301 | s1 := s1 + s2; 302 | strsswap.put(r, s1); 303 | dbb_get(dbb_idx, r1, t1); 304 | t1.next := t2.next; 305 | dbb_put(dbb_idx, r1, t1); 306 | dbb_free(dbb_idx, r2); 307 | dbm_free(dbm_mem, t2.recno); 308 | 309 | dbb_get(dbb_idx, t1.next, t2); 310 | t2.prev := r1; 311 | dbb_put(dbb_idx, t1.next, t2); 312 | end; 313 | end; 314 | merge := r; 315 | end; 316 | 317 | function append(r : dword; var pos : integer; p : pchar; var lnum:word) : dword; 318 | var s, src, s1, s2 : string; 319 | c : char; 320 | len : integer; 321 | rec : TExtStringRec; 322 | begin 323 | lnum := 0; 324 | if not ((r = 0) or (p = nil)) then begin 325 | s := ''; 326 | dbb_get(dbb_idx, r, rec); 327 | src := ''; 328 | if (rec.recno <> 0) and (rec.len <> 1) then dbm_get(dbm_mem, rec.recno, src, rec.len); 329 | while p^ <> #0 do begin 330 | c := p^; 331 | case c of 332 | #$0A: begin 333 | inc(lnum); 334 | s1 := ''; 335 | s2 := ''; 336 | len := length(src); 337 | if len > 0 then s1 := copy(src, 1, pos - 1); 338 | if pos <= len then s2 := copy(src, pos, len - pos + 1); 339 | s1 := s1 + s; 340 | rec.len := length(s1) + 1; 341 | if rec.len <> 1 then begin 342 | if rec.recno <> 0 then dbm_put(dbm_mem, rec.recno, s1, rec.len) 343 | else rec.recno := dbm_add(dbm_mem, s1, rec.len); 344 | end else begin 345 | dbm_free(dbm_mem, rec.recno); 346 | rec.recno := 0; 347 | end; 348 | dbb_put(dbb_idx, r, rec); 349 | r := strsswap.create(rec.next, r, s2); 350 | dbb_get(dbb_idx, r, rec); 351 | src := s2; 352 | pos := 1; 353 | s := ''; 354 | end; 355 | else if c <> #$0d then s := s + c; 356 | end; 357 | inc(p); 358 | end; 359 | if length(s) <> 0 then begin 360 | strsswap.get(r, s1); 361 | System.insert(s, s1, pos); 362 | inc(pos, length(s)); 363 | r := strsswap.put(r, s1); 364 | end; 365 | end; 366 | append := r; 367 | end; 368 | 369 | function split(r : dword; pos : integer) : dword; 370 | var s1, s2 : string; 371 | rec : TExtStringRec; 372 | begin 373 | s1 := ''; 374 | dbb_get(dbb_idx, r, rec); 375 | if rec.recno <> 0 then dbm_get(dbm_mem, rec.recno, s1, rec.len); 376 | dbm_free(dbm_mem, rec.recno); 377 | rec.recno := 0; 378 | s2 := trim(copy(s1, pos, length(s1) - pos + 1)); 379 | s1 := rtrim(copy(s1, 1, pos - 1)); 380 | rec.len := length(s1) + 1; 381 | if rec.len <> 1 then rec.recno := dbm_add(dbm_mem, s1, rec.len); 382 | dbb_put(dbb_idx, r, rec); 383 | strsswap.create(rec.next, r, s2); 384 | split := r; 385 | end; 386 | 387 | procedure init; 388 | begin 389 | FillChar(dbm_mem, SizeOf(DBMFile), #0); 390 | FillChar(dbb_idx, SizeOf(DBBFile), #0); 391 | dbm_rewritetemp(dbm_mem, MEM_BLK_SIZE); 392 | dbb_rewritetemp(dbb_idx, IDX_BLK_SIZE); 393 | end; 394 | 395 | procedure done; 396 | begin 397 | dbm_close(dbm_mem); 398 | dbb_close(dbb_idx); 399 | end; 400 | 401 | function from_file(fname : string; tab_size : integer; var errCode : integer; scrupdate : pointer) : dword; 402 | var root : dword; 403 | f : bfile; 404 | s : string; 405 | total : dword; 406 | position : dword; 407 | scrup : TPercentUpdateProc; 408 | tabs : string; 409 | prec, crec : TExtStringRec; 410 | pno, cno : dword; 411 | readed : integer; 412 | start_date : longint; 413 | begin 414 | scrup := TPercentUpdateProc(scrupdate); 415 | start_date := get_ticks; 416 | 417 | fillchar(f, sizeof(bfile), #0); 418 | fillchar(prec, sizeof(TExtStringRec), #0); 419 | fillchar(tabs[1], 255, #32); 420 | tabs[0] := chr(tab_size); 421 | 422 | root := 0; 423 | readed := 0; 424 | total := 0; 425 | position := 0; 426 | 427 | pno := 0; 428 | cno := 0; 429 | 430 | assign(f, fname); 431 | reset(f); 432 | if not IsOpen(f) then errCode := 104 else total := filesize(f); 433 | 434 | if total <> 0 then begin 435 | while not eof(f) do begin 436 | readln(f, s); 437 | remove_tabs(s, tabs); 438 | fillchar(crec, sizeof(TExtStringRec), #0); 439 | crec.prev := pno; 440 | crec.len := length(s) + 1; 441 | if s[0] <> #0 then crec.recno := dbm_add(dbm_mem, s, crec.len); 442 | cno := dbb_add(dbb_idx, crec); 443 | if root = 0 then root := cno; 444 | if pno <> 0 then begin 445 | prec.next := cno; 446 | dbb_put(dbb_idx, pno, prec); 447 | end; 448 | prec := crec; 449 | pno := cno; 450 | inc(readed, ord(s[0])); 451 | if readed > PROGRESS_UPDATE then begin 452 | if scrupdate <> nil then begin 453 | position := filepos(f); 454 | scrup(position, total, start_date); 455 | end; 456 | readed := 0; 457 | end; 458 | 459 | end; 460 | end; 461 | if scrupdate <> nil then begin 462 | position := filepos(f); 463 | scrup(position, total, start_date); 464 | end; 465 | if IsOpen(f) then close(f); 466 | 467 | if root = 0 then root := strsswap.new; 468 | from_file := root; 469 | end; 470 | 471 | procedure to_file(fname : string; r : dword; var errCode : integer; scrupdate : pointer); 472 | var f : bfile; 473 | s : string; 474 | total : dword; 475 | position : dword; 476 | scrup : TPercentUpdateProc; 477 | rec : TExtStringRec; 478 | writed : integer; 479 | start_date : longint; 480 | begin 481 | assign(f, fname); 482 | rewrite(f); 483 | if not isopen(f) then begin 484 | errCode := 105; 485 | exit; 486 | end; 487 | 488 | scrup := TPercentUpdateProc(scrupdate); 489 | start_date := get_ticks; 490 | 491 | total := strsswap.renum(r); 492 | position := 0; 493 | writed := 0; 494 | 495 | while r <> 0 do begin 496 | dbb_get(dbb_idx, r, rec); 497 | if rec.recno <> 0 then dbm_get(dbm_mem, rec.recno, s, rec.len) 498 | else s[0] := #0; 499 | writeln(f, s); 500 | r := rec.next; 501 | inc(writed, ord(s[0])); 502 | inc(position); 503 | if writed > PROGRESS_UPDATE then begin 504 | if scrupdate <> nil then begin 505 | scrup(position, total, start_date); 506 | end; 507 | writed := 0; 508 | end; 509 | end; 510 | truncate(f); 511 | close(f); 512 | end; 513 | 514 | function is_nil(r : dword) : boolean; 515 | begin 516 | is_nil := r = 0; 517 | end; 518 | 519 | end. 520 | --------------------------------------------------------------------------------