/sved/tags/2023.3/deflang.c |
---|
0,0 → 1,63 |
/* THIS FILE HAS BEEN GENERATED BY TLUMACZ (PART OF THE SVARLANG LIBRARY) */ |
const unsigned short svarlang_memsz = 375u; |
const unsigned short svarlang_string_count = 23u; |
char svarlang_mem[375] = { |
0x45,0x53,0x43,0x3d,0x4d,0x45,0x4e,0x55,0x00, |
0x55,0x4e,0x54,0x49,0x54,0x4c,0x45,0x44,0x00, |
0x53,0x41,0x56,0x45,0x44,0x00, |
0x55,0x6e,0x73,0x61,0x76,0x65,0x64,0x20,0x63,0x68,0x61,0x6e,0x67,0x65,0x73,0x20, |
0x77,0x69,0x6c,0x6c,0x20,0x62,0x65,0x20,0x6c,0x6f,0x73,0x74,0x2e,0x00, |
0x50,0x72,0x65,0x73,0x73,0x20,0x45,0x4e,0x54,0x45,0x52,0x20,0x74,0x6f,0x20,0x63, |
0x6f,0x6e,0x66,0x69,0x72,0x6d,0x2e,0x00, |
0x53,0x61,0x76,0x65,0x20,0x61,0x73,0x3a,0x00, |
0x4c,0x6f,0x61,0x64,0x3a,0x00, |
0x50,0x72,0x65,0x73,0x73,0x20,0x45,0x53,0x43,0x20,0x74,0x6f,0x20,0x63,0x61,0x6e, |
0x63,0x65,0x6c,0x2e,0x00, |
0x45,0x52,0x52,0x4f,0x52,0x00, |
0x46,0x49,0x4c,0x45,0x20,0x4e,0x4f,0x54,0x20,0x46,0x4f,0x55,0x4e,0x44,0x00, |
0x54,0x6f,0x6f,0x20,0x6d,0x61,0x6e,0x79,0x20,0x66,0x69,0x6c,0x65,0x73,0x00, |
0x5b,0x66,0x69,0x6c,0x65,0x31,0x2e,0x74,0x78,0x74,0x5d,0x20,0x2e,0x2e,0x2e,0x20, |
0x5b,0x66,0x69,0x6c,0x65,0x31,0x30,0x2e,0x74,0x78,0x74,0x5d,0x00, |
0x4c,0x6f,0x61,0x64,0x69,0x6e,0x67,0x00, |
0x53,0x76,0x65,0x64,0x2c,0x20,0x74,0x68,0x65,0x20,0x53,0x76,0x61,0x72,0x44,0x4f, |
0x53,0x20,0x65,0x64,0x69,0x74,0x6f,0x72,0x00, |
0x76,0x65,0x72,0x00, |
0x2f,0x6d,0x20,0x20,0x66,0x6f,0x72,0x63,0x65,0x20,0x6d,0x6f,0x6e,0x6f,0x63,0x68, |
0x72,0x6f,0x6d,0x65,0x20,0x6d,0x6f,0x64,0x65,0x00, |
0x2f,0x74,0x20,0x20,0x64,0x6f,0x20,0x6e,0x6f,0x74,0x20,0x65,0x78,0x70,0x61,0x6e, |
0x64,0x20,0x74,0x61,0x62,0x20,0x63,0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,0x73, |
0x00, |
0x4f,0x70,0x65,0x6e,0x20,0x66,0x69,0x6c,0x65,0x00, |
0x53,0x61,0x76,0x65,0x00, |
0x53,0x61,0x76,0x65,0x20,0x61,0x73,0x2e,0x2e,0x2e,0x00, |
0x43,0x6c,0x6f,0x73,0x65,0x20,0x66,0x69,0x6c,0x65,0x00, |
0x43,0x68,0x61,0x6e,0x67,0x65,0x20,0x45,0x4f,0x4c,0x00, |
0x51,0x75,0x69,0x74,0x00 |
}; |
unsigned short svarlang_dict[46] = { |
0x0000,0x0000, |
0x0001,0x0009, |
0x0002,0x0012, |
0x0004,0x0018, |
0x0005,0x0036, |
0x0006,0x004e, |
0x0007,0x0057, |
0x0008,0x005d, |
0x000a,0x0072, |
0x000b,0x0078, |
0x000c,0x0087, |
0x0101,0x0096, |
0x0102,0x00b3, |
0x0103,0x00bb, |
0x0104,0x00d4, |
0x010a,0x00d8, |
0x010b,0x00f2, |
0x0801,0x0113, |
0x0802,0x011d, |
0x0803,0x0122, |
0x0804,0x012d, |
0x0805,0x0138, |
0x0806,0x0143 |
}; |
/sved/tags/2023.3/makefile |
---|
0,0 → 1,58 |
# |
# sved's makefile -- requires Open Watcom 1.9 (wmake) |
# Copyright (C) 2023 Mateusz Viste |
# |
# usage: |
# wmake builds the sved.com binary |
# wmake release builds distribuable packages (svp, zip, sources...) |
CC = wcc |
CFLAGS = -0 -ms -os -wx -we -d0 -I=mdr\inc |
CFLAGS += -s |
LDFLAGS = -lr -mt -fm=sved.map -fe=sved.com |
LDLIBS = svarlang\svarlngs.lib mdr\mdrs2023.lib |
PVER = 2023.3 |
all: sved.com |
sved.com: sved.obj deflang.obj |
wcl $(LDLIBS) sved.obj deflang.obj $(LDFLAGS) |
upx -9 --8086 sved.com |
.c.obj: .autodepend |
$(CC) $(CFLAGS) $*.C |
# builds a SvarDOS package |
sved.svp: sved.com |
IF EXIST SVED.SVP DEL SVED.SVP |
mkdir bin |
mkdir appinfo |
mkdir doc |
mkdir doc\sved |
copy sved.com bin |
copy sved.lng bin |
copy sved.txt doc\sved |
echo version: $(PVER) > appinfo\sved.lsm |
echo description: SvarDOS text editor >> appinfo\sved.lsm |
zip -9rkDX -m sved.svp bin appinfo doc |
rmdir doc\sved |
rmdir doc |
rmdir bin |
rmdir appinfo |
# "normal" DOS distribution, ie. bunch of binaries in a zip file |
sved.zip: sved.com |
IF EXIST SVED.ZIP DEL SVED.ZIP |
zip -9rkDX sved.zip sved.com sved.lng sved.txt |
# source package (no binaries) |
sved_src.zip: |
IF EXIST SVED_SRC.ZIP DEL SVED_SRC.ZIP |
zip -9rkDX sved_src.zip *.txt *.c *.h *.lng makefile mdr nls svarlang |
release: sved.svp sved.zip sved_src.zip .symbolic |
clean: .symbolic |
del *.obj |
del sved.com |
/sved/tags/2023.3/mdr/history.txt |
---|
0,0 → 1,28 |
version xxxx (xx xxx xxxx) |
- new mdr_dos_selfexe() |
- new mdr_dos_truename() |
- new mdr_coutraw_str() and mdr_coutraw_crlf() |
- new mdr_dos_ctrlc_inhibit(), mdr_dos_ctrlc_enable(), mdr_dos_ctrlc_disable() |
- renamed keyb_getkey() to mdr_dos_getkey() |
- renamed keyb_flush() to mdr_dos_flushkeyb() |
- new mdr_dos_getkey2(), same as mdr_dos_getkey() but immune to CTRL+C |
- new mdr_dos_keypending() |
- removed keyb_getkey_ifany(): use mdr_dos_keypending + mdr_dos_getkey instead |
version 2023 (29 Jul 2023) |
- all routines are built as a library now |
- advertising MDR version (MDR_VER_MAJOR and MDR_VER_MINOR in VER.H) |
- added the SBDIGI driver (SoundBlaster Digitized sound) |
- added the COUT module (text-mode console output) |
- added the DOS module (mdr_dos_* functions) |
- added the UNZIP module for iteration over ZIP archives |
- added the BIOS module (with the mdr_bios_tickswait() function) |
- vid12: fast VRAM copy (vid12_vramcpy_* functions) |
- vid12: vid12_clrline() |
- vid12: fixed color mapping in vid12_setpalette() |
- vid12: added functions vid12_hline() and vid12_linepat() |
- vid12: fixed reverting the previous video mode at vid12_close() |
- vid12: optimized vid12_putpixel() - 17% faster |
version 2022 (09 Oct 2022) |
- initial public release |
/sved/tags/2023.3/mdr/inc/mdr/bios.h |
---|
0,0 → 1,35 |
/* |
* BIOS functions |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2014-2023 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_BIOS_H |
#define MDR_BIOS_H |
/* waits for ticks time (1 tick is roughly 55ms, an hour has 65543 ticks) |
* works on IBM PC, XT, AT - ie. it's always safe */ |
void mdr_bios_tickswait(unsigned short ticks); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/cout.h |
---|
0,0 → 1,83 |
/* |
* Console output |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2014-2023 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_COUT |
#define MDR_COUT |
/* inits the subsystem, fills arguments with: |
* w = screen width |
* h = screen height |
* Any of these arguments may be passed as NULL |
* Returns a color flag (0=mono, non-zero=color) */ |
unsigned char mdr_cout_init(unsigned char *w, unsigned char *h); |
/* get current attribute value under cursor and returns it */ |
int mdr_cout_getcurattr(void); |
void mdr_cout_close(void); |
void mdr_cout_cursor_hide(void); |
void mdr_cout_cursor_show(void); |
/* gets cursor's position on screen (row, column) and shape */ |
void mdr_cursor_getinfo(unsigned char *column, unsigned char *row, unsigned short *shape); |
void mdr_cout_locate(unsigned char row, unsigned char column); |
/* print a single character on screen */ |
void mdr_cout_char(unsigned char y, unsigned char x, char c, unsigned char attr); |
/* print a single character on screen, repeated count times */ |
void mdr_cout_char_rep(unsigned char y, unsigned char x, char c, unsigned char attr, unsigned char count); |
/* print a nul-terminated string on screen, up to maxlen characters |
* returns the number of characters actually displayed */ |
unsigned char mdr_cout_str(unsigned char y, unsigned char x, const char *s, unsigned char attr, unsigned char maxlen); |
/* clears screen, filling it with a single color attribute */ |
void mdr_cout_cls(unsigned char colattr); |
void mdr_cout_getconprops(unsigned char *termwidth, unsigned char *termheight, unsigned char *colorflag); |
/***************************************************************************** |
* functions below do not need mdr_cout_init() initialization, they can be * |
* used to output data to console right away, as they use DOS services. * |
*****************************************************************************/ |
/* output a single character to console */ |
void mdr_coutraw_char(char c); |
/* output a nul-terminated string */ |
void mdr_coutraw_str(const char *s); |
/* same as above, but followed with a CR/LF line terminator */ |
void mdr_coutraw_puts(const char *s); |
/* outputs a DOS-style (CR/LF) newline to console */ |
void mdr_coutraw_crlf(void); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/dos.h |
---|
0,0 → 1,113 |
/* |
* Functions interacting with DOS |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2014-2023 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_DOS_H |
#define MDR_DOS_H |
#include <time.h> /* time_t */ |
/* returns a far pointer to the current process PSP structure */ |
void far *mdr_dos_psp(void); |
/* returns a far pointer to the environment block of the current process */ |
char far *mdr_dos_env(void); |
/* looks for varname in the DOS environment and fills result with its value if |
* found. returns NULL if not found or if value is too big to fit in result |
* (reslimit exceeded). returns result on success. |
* NOTE: this function performs case-sensitive matches */ |
char *mdr_dos_getenv(char *result, const char *varname, unsigned short reslimit); |
/* fetches directory where the program was loaded from and return its length. |
* path string is never longer than 128 (incl. the null terminator) and it is |
* always terminated with a backslash separator, unless it is an empty string */ |
unsigned char mdr_dos_exepath(char *path); |
/* returns a far pointer to the full path and filename of the running program. |
* returns NULL on error. */ |
const char far *mdr_dos_selfexe(void); |
/* waits for a keypress and returns it |
* extended keys are returned ORed with 0x100 (example: PGUP is 0x149) */ |
int mdr_dos_getkey(void); |
/* Same as mdr_dos_getkey(), but this call cannot be aborted by CTRL+C */ |
int mdr_dos_getkey2(void); |
/* flush the keyboard buffer */ |
void mdr_dos_flushkeyb(void); |
/* poll stdin status, returns 0 if no character is pending in the keyboard |
* buffer, non-zero otherwise */ |
int mdr_dos_keypending(void); |
/* sets up the CTRL+C handler for the running program to a no-op - in other |
* words, after this call DOS will no longer abort the program on CTRL+C. |
* this is only valid for the duration of the program because DOS will restore |
* the original handler after the program exits. |
* |
* an alternative is mdr_dos_ctrlc_off(), but this does not inhibit the |
* handler, it sets DOS to not react to CTRL+C in the first place, and this |
* setting stays active after the program quits so the program should remember |
* to restore the original setting before quitting. */ |
void mdr_dos_ctrlc_inhibit(void); |
/* sets the DOS BREAK control OFF, ie. instructs DOS not to check for CTRL+C |
* during most input operations. returns the previous state of the break |
* control flag (0=disabled 1=enabled). this changes a global DOS flag that can |
* be checked on command line with the "BREAK" command, so the program should |
* take care to restore the initial setting before quitting. */ |
unsigned char mdr_dos_ctrlc_disable(void); |
/* sets the DOS BREAK control ON. see mdr_dos_ctrlc_disable() for details. */ |
void mdr_dos_ctrlc_enable(void); |
/* converts a "DOS format" 16-bit packed date into a standard (time_t) |
* unix timestamp. A DOS date is a 16-bit value: |
* YYYYYYYM MMMDDDDD |
* |
* day of month is always within 1-31 range; |
* month is always within 1-12 range; |
* year starts at 1980 and continues for 127 years */ |
time_t mdr_dos_date2unix(unsigned short d); |
/* converts a "DOS format" 16-bit packed time into hours, minutes and seconds |
* |
* A DOS time is a 16-bit value: |
* HHHHHMMM MMMSSSSS |
* |
* HHHHH = hours, always within 0-23 range |
* MMMMMM = minutes, always within 0-59 range |
* SSSSS = seconds/2 (always within 0-29 range) */ |
void mdr_dos_time2hms(unsigned char *h, unsigned char *m, unsigned char *s, unsigned short t); |
/* Determine the canonical name of the specified filename or path and writes |
* the result into result. The input path does not need to actually exist. |
* result is zeroed to an empty string on error. */ |
void mdr_dos_truename(char *result, const char *name); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/mouse.h |
---|
0,0 → 1,48 |
/* |
* Mouse routines |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2014-2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_MOUSE_H |
#define MDR_MOUSE_H |
/* init the mouse driver (and checks for presence of mouse support at same time) |
* returns 0 if no mouse is present, and the number of buttons otherwise */ |
int mouse_init(void); |
/* shows the mouse pointer */ |
void mouse_show(void); |
/* hides the mouse pointer */ |
void mouse_hide(void); |
/* get x/y coordinates of the mouse, and returns a bitfield with state of buttons */ |
int mouse_getstate(int *x, int *y); |
/* get x/y coordinates of the mouse when the last button release occured since last check. |
returns the id of the button pressed (1 or 2), or 0 if no event occured. */ |
int mouse_fetchrelease(int *x, int *y); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/pcx.h |
---|
0,0 → 1,50 |
/* |
* PCX-loading routines |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_PCX_H |
#define MDR_PCX_H |
struct pcx_hdr { |
unsigned char rle; |
unsigned char bpp; |
unsigned short max_x; |
unsigned short max_y; |
unsigned short bytes_per_scanline; |
struct { |
unsigned char r; |
unsigned char g; |
unsigned char b; |
} pal[256]; |
}; |
int pcx_anal(struct pcx_hdr *h, FILE *fd, unsigned long offset, unsigned short len); |
int pcx_load(void *ptr, size_t ptrsz, const struct pcx_hdr *h, FILE *fd, unsigned long offset); |
/* convert img to 8bpp if needed (ie unpack 2 and 4bpp data to 8bpp) */ |
int pcx_convto8bpp(void *img, const struct pcx_hdr *h); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/rs232.h |
---|
0,0 → 1,47 |
/* |
* Reading from and writing to an RS-232 port |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2015-2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_RS232_H |
#define MDR_RS232_H |
/* get the I/O port for COMx (1..4) */ |
unsigned short rs232_getport(int x); |
/* check if the COM port is ready for write. loops for some time waiting. |
* returns 0 if port seems ready eventually, non-zero otherwise. can be used |
* to verify the rs232 presence */ |
int rs232_check(unsigned short port); |
/* write a byte to the COM port at 'port'. this function will block if the |
* UART is not ready to transmit yet. */ |
void rs232_write(unsigned short port, int data); |
/* read a byte from COM port at 'port'. returns the read byte, or -1 if |
* nothing was available to read. */ |
int rs232_read(unsigned short port); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/sbdigi.h |
---|
0,0 → 1,57 |
/* |
* SoundBlaster routines for DSP driving |
* |
* Copyright (C) 2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_SBDIGI_H |
#define MDR_SBDIGI_H |
struct sbdigi_ctx; |
/* initializes the SoundBlaster DSP chip |
* blaster must point to a BLASTER environment string (like "A220 I5 D1") |
* returns a pointer to a context, NULL on error |
* NOTE: DSP's state after initialization may or may not be muted, depending |
* on the exact hardware revision. use sbdigi_spkoff() to make sure it is |
* unmuted */ |
struct sbdigi_ctx *sbdigi_init(const char *blaster); |
/* unmutes the SoundBlaster DSP */ |
void sbdigi_spkon(struct sbdigi_ctx *ctx); |
/* mutes the SoundBlaster DSP */ |
void sbdigi_spkoff(struct sbdigi_ctx *ctx); |
/* plays a short sample |
* ctx - DSP context, as returned by sbdigi_init() |
* buf - pointer to sample data (must be PCM, 8000 Hz, mono, 8-bit unsigned |
* len - length of the sample, in bytes |
* NOTES: this routine uses DMA to transfer memory. This has two implications: |
* 1. the routine will return almost immediately, while the sound is playing |
* 2. sample data must be contained in a buffer that does NOT cross a 64K page |
* because DMA transfers are unable to cross 64K boundaries */ |
void sbdigi_playsample(struct sbdigi_ctx *ctx, void *buf, unsigned short len); |
/* shuts down the DSP and frees context memory */ |
void sbdigi_quit(struct sbdigi_ctx *ctx); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/timer.h |
---|
0,0 → 1,52 |
/* |
* High-resolution timing routines (PIT reprogramming) |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2014-2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_TIMER_H |
#define MDR_TIMER_H |
/* reset the timer value, this can be used by the application to make sure |
* no timer wrap occurs during critical parts of the code flow */ |
void timer_reset(void); |
/* This routine will stop the fast clock if it is going. It has void return |
* value so that it can be an exit procedure. */ |
void timer_stop(void); |
/* This routine will start the fast clock rate by installing the |
* handle_clock routine as the interrupt service routine for the clock |
* interrupt and then setting the interrupt rate up to its higher speed |
* by programming the 8253 timer chip. |
* This routine does nothing if the clock rate is already set to |
* its higher rate, but then it returns -1 to indicate the error. */ |
void timer_init(void); |
/* This routine will return the present value of the time, which is |
* read from the nowtime structure. Interrupts are disabled during this |
* time to prevent the clock from changing while it is being read. */ |
void timer_read(unsigned long *res); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/trigint.h |
---|
0,0 → 1,46 |
/* |
* Routines for computation of basic transcendental functions sin and cos. |
* These routines use only integers, hence they do not require an FPU nor any |
* kind of FPU emulation. Works reasonably fast even on an 8086 CPU. |
* |
* The results are computed using polynomial approximations. Their precision |
* is not expected to be ideal, but "good enough" for common usage. |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_TRIGINT_H |
#define MDR_TRIGINT_H |
/* Computes the cosine value for the given radian. |
* The radian argument must be provided multiplied by 1000. |
* Returns the cosine value multiplied by 1000. */ |
short trigint_cos(short rad1000); |
/* Computes the sine value for the given radian angle. |
* The radian argument must be provided multiplied by 1000. |
* Returns the cosine value multiplied by 1000. */ |
short trigint_sin(short rad1000); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/unzip.h |
---|
0,0 → 1,58 |
/* |
* Function to iterate through files in a ZIP archive. |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2012-2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_UNZIP |
#define MDR_UNZIP |
#include <stdio.h> /* FILE * */ |
#define ZIP_FLAG_ISADIR 1 |
#define ZIP_FLAG_ENCRYPTED 2 |
#define ZIP_METH_STORE 0 |
#define ZIP_METH_DEFLATE 8 |
struct mdr_zip_item { |
unsigned long filelen; |
unsigned long compressedfilelen; |
unsigned long crc32; |
unsigned long dataoffset; /* offset in the file where compressed data starts */ |
unsigned long nextidxoffset; /* offset in the file of the next zip record, used by mdr_zip_iter() */ |
unsigned short dosdate; /* datestamp of the file (DOS packed format) */ |
unsigned short dostime; /* timestamp of the file (DOS packed format) */ |
unsigned short compmethod; /* compression method (ZIP_METH_xxx) */ |
unsigned char flags; /* see ZIP_FLAG_xxx above */ |
char fname[256]; /* filename */ |
}; |
/* returns next item found in zip file. this is supposed to be called |
* iteratively, passing the previous mdr_zipitem struct each time (z must be |
* all zeroed out on first call). |
* returns 0 on success, neg on error, 1 on end of archive */ |
int mdr_zip_iter(struct mdr_zip_item *z, FILE *fd); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/ver.h |
---|
0,0 → 1,33 |
/* |
* MDR version |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2014-2023 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_VER_H |
#define MDR_VER_MAJOR 2023 |
#define MDR_VER_MINOR 0 |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/vid12.h |
---|
0,0 → 1,72 |
/* |
* a few functions for mode 12h programming (640x480 4bpp) |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_VID12_H |
#define MDR_VID12_H |
/* init video mode 12h (640x480x16c) */ |
void vid12_init(void); |
/* Wait until VBLANK */ |
void vid12_waitvblank(void); |
/* clear screen using color |
* this function is fastest when color is 0 or 15 */ |
void vid12_cls(unsigned char color); |
/* clear a single scanline (0..479) with a solid color (0..15) |
* this function is fastest when color is 0 or 15 */ |
void vid12_clrline(unsigned short line, unsigned char color); |
/* fill lines from linefirst to linelast with an 8 pixels pattern |
* linelast must be equal to or greater than linelast |
* pattern must be 8 bytes long */ |
void vid12_linepat(unsigned short linefirst, unsigned short linelast, const unsigned char *pattern); |
void vid12_close(void); |
void vid12_putpixel(unsigned short x, unsigned short y, unsigned char col); |
/* draws a horizonatal line from [x1,y] to [x2,y] */ |
void vid12_hline(unsigned short y, unsigned short x1, unsigned short x2, unsigned char color); |
void vid12_putscanline(unsigned short scanline, const unsigned char *pixels); |
/* prepares VGA for a VRAM-to-VRAM copy operation */ |
void vid12_vramcpy_prep(void); |
/* fast (VRAM-to-VRAM) copy of a scanline (0..479) to another scanline. |
* vid12_vramcpy_prep() must be called before and vid12_vramcpy_done must be |
* called after one or more vid12_vramcpy_scanline() calls. */ |
void vid12_vramcpy_scanline(unsigned short dst, unsigned short src); |
/* sets VGA back to its normal state after VRAM-to-VRAM operations */ |
void vid12_vramcpy_done(void); |
void vid12_setpalette(unsigned char index, unsigned char r, unsigned char g, unsigned char b); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/video.h |
---|
0,0 → 1,94 |
/* |
* video library - provides a few functions for mode 4 and 13h programming. |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2014-2023 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_VIDEO_H |
#define MDR_VIDEO_H |
#define VIDEO_DBUF 1 |
struct video_handler { |
unsigned char far *dbuf; |
int flags; |
int mode; |
unsigned char lastmode; |
}; |
/* returns 0 if no VGA has been detected, non-zero otherwise */ |
int video_detectvga(void); |
/* returns 0 if no EGA has been detected, non-zero otherwise */ |
int video_detectega(void); |
/* init video mode. either 0x04 for CGA or 0x13 for VGA */ |
struct video_handler *video_open(int mode, int flags); |
/* reads a screen dump from file and puts it to the screen buffer */ |
void video_file2screen(struct video_handler *handler, char *file); |
/* load count colors of palette from array of rgb triplets */ |
void video_loadpal(const unsigned char *pal, int count, int offset); |
/* Wait until VBLANK */ |
void video_waitvblank(void); |
void video_flip(struct video_handler *handler); |
/* copies line ysrc over ydst in CGA mode memory */ |
void video_cgalinecopy(struct video_handler *handler, int ydst, int ysrc); |
/* clear screen using color */ |
void video_cls(struct video_handler *handler, unsigned char color); |
/* renders a sprite of width and height dimensions onscreen, starting at specified x/y location |
coloffset is an offset to add to color indexes, while transp is the index of the transparent color (set to -1 if none) */ |
void video_putsprite(struct video_handler *handler, unsigned char *sprite, int x, int y, int width, int height, int coloffset, int transp, int maxcol); |
/* same as video_putsprite(), but reads the sprite from a file */ |
void video_putspritefromfile(struct video_handler *handler, char *file, long foffset, int x, int y, int width, int height, int coloffset, int transp, int maxcol); |
void video_close(struct video_handler *handler); |
void video_rputpixel(struct video_handler *handler, int x, int y, unsigned char col, int repeat); |
/* render a horizontal line of length len starting at x/y */ |
void video_hline(struct video_handler *handler, int x, int y, int len, unsigned char color); |
/* render a vertical line of length len starting at x/y */ |
void video_vline(struct video_handler *handler, int x, int y, int len, unsigned char color); |
void video_line(struct video_handler *handler, int x1, int y1, int x2, int y2, unsigned char color); |
void video_rect(struct video_handler *handler, int x, int y, int width, int height, unsigned char color); |
/* renders a rectangle on screen, at position x/y, filled with color */ |
void video_rectfill(struct video_handler *handler, int x, int y, int width, int height, unsigned char color); |
void video_setpalette(unsigned char index, unsigned char r, unsigned char g, unsigned char b); |
void video_getpalette(unsigned char index, unsigned char *r, unsigned char *g, unsigned char *b); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/wave.h |
---|
0,0 → 1,42 |
/* |
* WAVE-loading routines |
* |
* Copyright (C) 2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_WAVE_H |
#define MDR_WAVE_H |
struct wave_t { |
unsigned short format; |
unsigned short channels; |
unsigned short rate; |
unsigned short bitdepth; |
unsigned long dataoffset; |
unsigned long len; |
}; |
/* looks at an open WAVE file and fills the wav structure with related |
* information (format, number of channels, bit depth, data rate, etc) |
* returns 0 on success */ |
int wave_anal(struct wave_t *wav, FILE *fd); |
#endif |
/sved/tags/2023.3/mdr/inc/mdr/xms.h |
---|
0,0 → 1,51 |
/* |
* XMS driver |
* |
* This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io |
* Published under the terms of the MIT License, as stated below. |
* |
* Copyright (C) 2014-2022 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef MDR_XMS_H |
#define MDR_XMS_H |
struct xms_struct { |
unsigned int handle; |
long memsize; /* allocated memory size, in bytes */ |
}; |
/* checks if a XMS driver is installed, inits it and allocates a memory block of memsize K-bytes. |
* if memsize is 0, then the maximum possible block will be allocated. |
* returns the amount of allocated memory (in K-bytes) on success, 0 otherwise. */ |
unsigned int xms_init(struct xms_struct *xms, unsigned int memsize); |
/* free XMS memory */ |
void xms_close(struct xms_struct *xms); |
/* copies a chunk of memory from conventional memory into the XMS block. |
returns 0 on sucess, non-zero otherwise. */ |
int xms_push(struct xms_struct *xms, void far *src, unsigned int len, long xmsoffset); |
/* copies a chunk of memory from the XMS block into conventional memory */ |
int xms_pull(struct xms_struct *xms, long xmsoffset, void far *dst, unsigned int len); |
#endif |
/sved/tags/2023.3/mdr/mdrs2023.lib |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/sved/tags/2023.3/mdr/readme.txt |
---|
0,0 → 1,77 |
Mateusz' DOS Routines |
http://mdr.osdn.io |
Mateusz' DOS Routines (MDR) is a collection of C library that contain a variety |
of routines to ease the development of real mode DOS applications. |
These routines are mostly targeted at the Open Watcom compiler, but might work |
with other C compilers as well. |
All the routines have been created by Mateusz Viste and are published under the |
terms of the MIT license. |
List of available modules: |
BIOS BIOS-based functions |
COUT console output (writing to text-mode display) |
DOS functions interacting with DOS |
KEYB basic functions to interact with the keyboard |
MOUSE mouse routines |
PCX parsing, loading and uncompressing PCX images |
RS232 writing to and reading from an RS-232 ("COM") port |
SBDIGI playing digitized sounds with a SoundBlaster-compatible card |
TIMER high-resolution timer, relies on PIT reprogramming |
TRIGINT sin and cos functions using integers only (8086-compatible) |
UNZIP iteration over ZIP archives (no decompression code) |
VID12 driver for mode 12h VGA graphic (640x480, 16 colors) |
VIDEO drivers for 320x200 video modes (256 colors on VGA, 16 colors on CGA) |
WAVE parsing and loading WAVE sound files |
XMS detecting and using XMS memory to store data |
Documentation is contained within header (*.H) files. |
+============================================================================+ |
| USAGE | |
+============================================================================+ |
Using MDR is no different than using any other library: you need to include |
the header file(s) you wish to rely on and pass the lib file that matches your |
memory model (small/compact/medium/large) to your linker. |
Example program, KBTEST.C: |
#include <mdr\keyb.h> |
int main(void) { |
keyb_getkey(); |
return(0); |
} |
How to compile with the Watcom C Compile and Link Utility: |
wcl -ms kbtest.c mdrs2023.lib |
+============================================================================+ |
| COMPILATION FROM SOURCES | |
+============================================================================+ |
Should you wish to compile MDR from souces instead of relying on precompiled |
LIB binaries, you will need the Watcom (or Open Watcom) C compiler and use its |
wmake utility as follows: |
wmake clean |
wmake model=<MEMORY MODEL> |
valid options are: |
wmake model=s |
wmake model=c |
wmake model=m |
wmake model=l |
============================================================================== |
/sved/tags/2023.3/nls/en_utf8.txt |
---|
0,0 → 1,52 |
############################################################################# |
# SVED IN ENGLISH # |
############################################################################# |
############################################################################# |
# # |
# IMPORTANT: Translations should be as compact as possible so they do not # |
# increase Sved's footprint. New translation files should be no larger than # |
# the biggest existing translation. Run REGEN.BAT to see current sizes. # |
# # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=MENU |
0.1:UNTITLED |
0.2:SAVED |
0.4:Unsaved changes will be lost. |
0.5:Press ENTER to confirm. |
0.6:Save as: |
0.7:Load: |
0.8:Press ESC to cancel. |
0.10:ERROR |
0.11:FILE NOT FOUND |
0.12:Too many files |
#################### |
# CONSOLE MESSAGES # |
#################### |
1.1:[file1.txt] ... [file10.txt] |
1.2:Loading |
1.3:Sved, the SvarDOS editor |
1.4:ver |
1.10:/m force monochrome mode |
1.11:/t do not expand tab characters |
######## |
# MENU # |
######## |
8.1:Open file |
8.2:Save |
8.3:Save as... |
8.4:Close file |
8.5:Change EOL |
8.6:Quit |
/sved/tags/2023.3/nls/fr_utf8.txt |
---|
0,0 → 1,53 |
############################################################################# |
# SVED IN FRENCH # |
# translated from English by Mateusz Viste # |
############################################################################# |
############################################################################# |
# # |
# IMPORTANT: Translations should be as compact as possible so they do not # |
# increase Sved's footprint. New translation files should be no larger than # |
# the biggest existing translation. Run REGEN.BAT to see current sizes. # |
# # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ÉCHAP=MENU |
0.1:SANS NOM |
0.2:OK |
0.4:Les données non enreg. seront perdues |
0.5:ENTRÉE pour valider |
0.6:Enreg. sous: |
0.7:Ouvrir: |
0.8:ÉCHAP pour annuler |
0.10:ERREUR |
0.11:FICHIER NON TROUVÉ |
0.12:Trop de fichiers |
#################### |
# CONSOLE MESSAGES # |
#################### |
1.1:[fich1.txt] ... [fich10.txt] |
1.2:Charg. |
1.3:Sved, l'éditeur SvarDOS |
1.4:ver |
1.10:/m mode monochrome forcé |
1.11:/t ne déplie pas les tabul. |
######## |
# MENU # |
######## |
8.1:Ouvrir fichier |
8.2:Enregistrer |
8.3:Enr. sous... |
8.4:Fermer fichier |
8.5:Changmnt EOL |
8.6:Sortir |
/sved/tags/2023.3/nls/pl_utf8.txt |
---|
0,0 → 1,53 |
############################################################################# |
# SVED IN POLISH # |
# translated from English by Mateusz Viste # |
############################################################################# |
############################################################################# |
# # |
# IMPORTANT: Translations should be as compact as possible so they do not # |
# increase Sved's footprint. New translation files should be no larger than # |
# the biggest existing translation. Run REGEN.BAT to see current sizes. # |
# # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=MENU |
0.1:BEZ NAZWY |
0.2:ZAPISANO |
0.4:Niezapisane zmiany będą utracone. |
0.5:Potwierdź z ENTER. |
0.6:Zapisz jako: |
0.7:Otwórz: |
0.8:Anuluj z ESC. |
0.10:BŁĄD |
0.11:NIE ZNALEZIONO PLIKU |
0.12:Zbyt wiele plików |
################ |
# USAGE SCREEN # |
################ |
1.1:[plik1.txt] ... [plik10.txt] |
1.2:Ładuję |
1.3:Sved, edytor systemu SvarDOS |
1.4:wersja |
1.10:/m wymusza tryb cz./biały |
1.11:/t nie rozwija znaków tabulacji |
######## |
# MENU # |
######## |
8.1:Otwórz plik |
8.2:Zapisz |
8.3:Zapisz jako... |
8.4:Zamknij plik |
8.5:Zmień EOL |
8.6:Wyjdź |
/sved/tags/2023.3/nls/regen.bat |
---|
0,0 → 1,13 |
@ECHO OFF |
utf8tocp 437 en_utf8.txt > en.txt |
utf8tocp 850 fr_utf8.txt > fr.txt |
utf8tocp maz pl_utf8.txt > pl.txt |
utf8tocp 866 ru_utf8.txt > ru.txt |
utf8tocp 857 tr_utf8.txt > tr.txt |
..\svarlang\tlumacz en fr pl ru tr |
move /y out.lng ..\sved.lng |
move /y deflang.c .. |
del ??.txt |
/sved/tags/2023.3/nls/ru_utf8.txt |
---|
0,0 → 1,53 |
############################################################################# |
# SVED IN RUSSIAN # |
# translated from English by Mateusz Viste # |
############################################################################# |
############################################################################# |
# # |
# IMPORTANT: Translations should be as compact as possible so they do not # |
# increase Sved's footprint. New translation files should be no larger than # |
# the biggest existing translation. Run REGEN.BAT to see current sizes. # |
# # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=МЕНЮ |
0.1:БЕЗ ИМЕНИ |
0.2:СОХРАНЕН |
0.4:Вы потеряете несохраненные данные. |
0.5:Подтвердите с ENTER. |
0.6:Сохранить как: |
0.7:Загрузка: |
0.8:Отмена с ESC. |
0.10:ОШИБКА |
0.11:ФАЙЛ НЕ НАЙДЕН |
0.12:Слишком много файлов |
#################### |
# CONSOLE MESSAGES # |
#################### |
1.1:[файл1.txt] ... [файл10.txt] |
1.2:Читаю |
1.3:Sved, редактор системы SvarDOS |
1.4:версия |
1.10:/m черн/бел режим |
1.11:/t не расширять табуляцию |
######## |
# MENU # |
######## |
8.1:Открыть файл |
8.2:Сохранить |
8.3:Сохранить как... |
8.4:Закрыть файл |
8.5:Изменить EOL |
8.6:Выход |
/sved/tags/2023.3/nls/tr_utf8.txt |
---|
0,0 → 1,54 |
############################################################################# |
# SVED IN TURKISH # |
# Translated from English by Berki Yenigun # |
############################################################################# |
############################################################################# |
# # |
# IMPORTANT: Translations should be as compact as possible so they do not # |
# increase Sved's footprint. New translation files should be no larger than # |
# the biggest existing translation. Run REGEN.BAT to see current sizes. # |
# # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=MENÜ |
0.1:BAŞLIKSIZ |
0.2:KAYDEDİLDİ |
0.4:Değişiklikler kaybolacak. |
0.5:Onay için ENTER'a basın. |
0.6:Farklı kaydet: |
0.7:Yükle: |
0.8:İptal için ESC'e basın. |
0.10:HATA |
0.11:DOSYA BULUNAMADI |
0.12:Çok fazla dosya |
#################### |
# CONSOLE MESSAGES # |
#################### |
1.1:[dosya1.txt] ... [dosya10.txt] |
1.2:Yükleniyor |
1.3:Sved, SvarDOS düzenleyicisi |
1.4:sürüm |
1.10:/m tek renkli kipi zorla |
1.11:/t sekmeleri genişletme |
######## |
# MENU # |
######## |
8.1:Dosya aç |
8.2:Kaydet |
8.3:Farklı kaydet... |
8.4:Dosyayı kapat |
8.5:EOL değiştir |
8.6:Çık |
/sved/tags/2023.3/svarlang/history.txt |
---|
0,0 → 1,28 |
20230730 |
- dropped svarlang_autoload() (replaced by more specialized functions below) |
- added svarlang_autoload_exepath() and svarlang_autoload_nlspath() |
- svarlang_load() simplified so it takes the target filename as an argument |
- file access relies on fopen() when svarlang is compiled with -DWITHSTDIO |
- new file format: sorted dictionary for faster lookup (by Bernd Boeckmann) |
breaking change! See svarlang.txt for file format specification |
20230630 |
- tlumacz.exe warns about empty strings (patch by Bernd Boeckmann) |
- tlumacz.exe does not abort when a malformed line is found |
20230629 |
- deflang.c has each message on a different line so it is nicer to VCSes |
20230628 |
- added support for \e sequences in translation strings |
- implemented svarlang_getver() |
20220314 |
- added support for flagging strings as being "dirty", eg: ?1.1:Hello, World |
20220309 |
- static lib buffer is sized to fit the largest lang block +5% of margin |
(was: twice the size of the reference language) |
20220226 |
- replaced fopen() and friends by direct DOS calls (smaller memory footprint) |
/sved/tags/2023.3/svarlang/svarlang.h |
---|
0,0 → 1,79 |
/* This file is part of the svarlang project and is published under the terms |
* of the MIT license. |
* |
* Copyright (C) 2021-2023 Mateusz Viste |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#ifndef SVARLANG_H |
#define SVARLANG_H |
/* library version */ |
#define SVARLANGVER "20230730" |
/* returns a pointer to a string with the SvarLANG's library version, |
* independently of the SVARLANGVER string above. */ |
const char *svarlang_getver(void); |
/* loads lang translations from file fname. |
* |
* only the two first letters of the lang strings are meaningful and they are |
* case insensitive. |
* |
* a typical call would be: svarlang_load("myprog.lng", "PL"); |
* |
* this function returns 0 on success, non-zero otherwise. It is still possible |
* to call svarlang_strid() after a load failure, the previously loaded |
* language will be used then, or the default language if no loading has been |
* done yet. */ |
int svarlang_load(const char *fname, const char *lang); |
/* tries loading lang strings from a file located in the executable's |
* directory that is named like the executable but with an *.LNG extension. |
* this is certainly the most practical way of loading svarlang. |
* selfexe should point to the executable's full filename path (either relative |
* or absolute). You may want to pass argv[0] or __argv[0] there. example: |
* |
* svarlang_autoload_exepath(argv[0], getenv("LANG")); |
*/ |
int svarlang_autoload_exepath(const char *selfexe, const char *lang); |
/* this looks in a list of paths separated by ';' to locate a translation file |
* for progname. this might be called by some FreeDOS programs that rely on the |
* NLSPATH environment variable for locating strings. example: |
* |
* svarlang_autoload_pathlist("myprog", getenv("NLSPATH"), getenv("LANG")); |
*/ |
int svarlang_autoload_pathlist(const char *progname, const char *pathlist, const char *lang); |
/* Returns a pointer to the string "id". Does not require svalang_load() to be |
* executed, but then it will only return the reference language strings. |
* a string id is the concatenation of the CATS-style identifiers, for example |
* string 1,0 becomes 0x0100, string 2.10 is 0x020A, etc. |
* It NEVER returns NULL, if id not found then an empty string is returned */ |
const char *svarlang_strid(unsigned short id); |
/* a convenience definition to fetch strings by their CATS-style pairs instead |
* of the 16-bit id. */ |
#define svarlang_str(x, y) svarlang_strid((x << 8) | y) |
#endif |
/sved/tags/2023.3/svarlang/svarlang.txt |
---|
0,0 → 1,123 |
SVARLANG.LIB - THE SVARDOS TRANSLATION C LIBRARY |
Copyright (C) 2021-2023 Mateusz Viste |
SvarLANG is a library and toolset for enabling SvarDOS applications to easily |
support multiple languages. It is part of the SvarDOS project. |
Homepage: http://svardos.org/svarlang/ |
### PREPARING TRANSLATION FILES ############################################### |
The translation files must be CATS-style text files in the usual format: |
1.1:Hello, World! |
1.2:Help screen |
2.0:Type /? for more options |
The files must be named as EN.TXT, DE.TXT, FR.TXT, etc. Then, they must be |
converted into SvarLANG's binary format using the TLUMACZ tool: |
tlumacz en fr pl (...) |
The first language provided in the command line is the reference language and |
is used both as the default (embedded in the application) language, as well as |
to substitute messages missing in other languages. |
TLUMACZ computes two files: |
* OUT.LNG - the binary file that contains all translations |
* DEFLANG.C - the default translations that will be embedded into the program |
Then, DEFLANG.C must be compiled and linked to your program along with |
SVARLNGx.LIB. From there you will be able to use SvarLANG calls, like this |
very basic example: |
svarlang_load("myprogram.lng", "pl"); /* load PL lang from myprogram.lng */ |
puts(svarlang_str(2, 0)); /* display the string with id 2.0 */ |
A more practical, real-world example would probably be this one: |
svarlang_autoload_exepath(argv[0], getenv("LANG")); |
puts(svarlang_str(2, 0)); |
Read svarlang.h for more information about available functions. |
### ESCAPED CHARACTERS ######################################################## |
Translation strings may contain some escaped characters. At this time only the |
following escaped characters are supported: \e \r \n \t and \\ |
### DIRTY STRINGS ############################################################# |
In the CATS-style source translation, lines may be prefixed with a '?' sign: |
?1.1:Hello, World! |
Such string is used by tlumacz like any other, but it is also reported on the |
command-line with a warning about the line being "dirty" (that is, requiring |
to be reviewed by a translator). |
### ENVIRONMENT ############################################################### |
The program translation file should be named "PROGNAME.LNG", where PROGNAME |
is the program's name. This file should be placed in a well-known location, |
typically the program's own directory. |
The %LANG% environment variable usually defines what language should be loaded, |
albeit the program can just as well provide its own controls for language |
selection and pass this information to svarlang_load() accordingly. |
### WHY IS IT BETTER THAN CATS? ############################################### |
The CATS library is heavier and slower, as it embeds a text-file parser. |
Translations also take more disk space since each language is stored in a |
separate file, leading to cluster waste. Finally, CATS requires default strings |
to be part of the application's source code, while SvarLANG keeps all strings |
in TXT files and embedds the default one inside the application in an automated |
way at compile time. |
There is also a licensing issue: CATS/Kitten libraries are published under the |
terms of a viral, corrosive license. SvarLANG, on the other hand, is published |
under a truly free, liberal MIT license. |
### FILE FORMAT ############################################################### |
File = |
magic : Char[4] := "SvL\x1a" (ie. "SvL" followed with a 0x1a char) |
; 0x1a is an end-of-file marker that prevents TYPE garbage |
num_strings : U16 |
languages : array[num_languages] of Language |
Language = |
lang_id : Char[2] |
len_strings : U16 := SizeOf(strings) |
dictionary : StringDict |
strings : array[File.num_strings] of StringZ |
StringDict = |
elements : array[File.num_strings] of DictEntry |
; sorted by DictEntry.Id |
DictEntry = |
id : U16 |
offset : U16 |
; relative to Language.strings[0] |
StringZ = array[?] of Char ; zero-terminated string |
NOTE: All numeric values are stored in x86 (little endian) order. |
####################################################################### EOF ### |
/sved/tags/2023.3/svarlang/svarlngs.lib |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/sved/tags/2023.3/svarlang/tlumacz.exe |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/x-dosexec |
Property changes: |
Added: svn:mime-type |
+application/x-dosexec |
\ No newline at end of property |
/sved/tags/2023.3/sved.c |
---|
0,0 → 1,1320 |
/* Sved, the SvarDOS editor |
* |
* Copyright (C) 2023 Mateusz Viste |
* |
* Sved is released under the terms of the MIT license. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
* of this software and associated documentation files (the "Software"), to |
* deal in the Software without restriction, including without limitation the |
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
* sell copies of the Software, and to permit persons to whom the Software is |
* furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#include <dos.h> /* _dos_open(), _dos_read(), _dos_close(), ... */ |
#include <fcntl.h> /* O_RDONLY, O_WRONLY */ |
#include <string.h> |
#include "mdr\bios.h" |
#include "mdr\cout.h" |
#include "mdr\dos.h" |
#include "svarlang\svarlang.h" |
#define PVER "2023.3" |
#define PDATE "2023" |
/***************************************************************************** |
* global variables and definitions * |
*****************************************************************************/ |
/* preload the mono scheme (to be overloaded at runtime if color adapter present) */ |
static unsigned char SCHEME_TEXT = 0x07, |
SCHEME_MENU = 0x70, |
SCHEME_MENU_CUR= 0x0f, |
SCHEME_MENU_SEL= 0x00, |
SCHEME_STBAR1 = 0x70, |
SCHEME_STBAR2 = 0x70, /* greyed out information */ |
SCHEME_STBAR3 = 0x70, /* query */ |
SCHEME_SCROLL = 0x70, |
SCHEME_MSG = 0x70, |
SCHEME_ERR = 0x70; |
static unsigned char screenw, screenh, screenlastrow, screenlastcol; |
static unsigned char glob_monomode, glob_tablessmode; |
static struct { |
unsigned char from; |
unsigned char to; |
unsigned char statusbar; |
} uidirty = {0, 0xff, 1}; /* make sure to redraw entire UI at first run */ |
#define SCROLL_CURSOR 0xB1 |
struct line { |
unsigned short len; |
struct line far *next; |
struct line far *prev; |
char payload[1]; |
}; |
struct file { |
struct line far *cursor; |
unsigned short xoffset; |
unsigned short cursorposx; |
unsigned short cursorposy; |
unsigned short totlines; |
unsigned short curline; |
unsigned short curline_prev; |
char lfonly; /* set if line endings are LF (CR/LF otherwise) */ |
char modflag; /* non-zero if file has been modified since last save */ |
char modflagprev; |
char fname[128]; |
}; |
/***************************************************************************** |
* functions * |
*****************************************************************************/ |
static struct line far *line_calloc(unsigned short siz) { |
struct line far *res; |
unsigned int seg; |
if (_dos_allocmem((sizeof(struct line) + siz + 15) / 16, &seg) != 0) return(NULL); |
res = MK_FP(seg, 0); |
res->len = 0; |
res->next = NULL; |
res->prev = NULL; |
return(res); |
} |
static void line_free(struct line far *ptr) { |
_dos_freemem(FP_SEG(ptr)); |
} |
static int curline_resize(struct file far *db, unsigned short newsiz) { |
unsigned int maxavail; |
struct line far *newptr; |
/* try resizing the block (much faster) */ |
if (_dos_setblock((sizeof(struct line) + newsiz + 15) / 16, FP_SEG(db->cursor), &maxavail) == 0) return(0); |
/* create a new block and copy data over */ |
newptr = line_calloc(newsiz); |
if (newptr == NULL) return(-1); |
_fmemmove(newptr, db->cursor, sizeof(struct line) + db->cursor->len); |
/* rewire the linked list */ |
db->cursor = newptr; |
if (newptr->next) newptr->next->prev = newptr; |
if (newptr->prev) newptr->prev->next = newptr; |
return(0); |
} |
/* adds a new line at cursor position into file linked list and advance cursor |
* returns non-zero on error */ |
static int line_add(struct file *db, const char far *line, unsigned short slen) { |
struct line far *l; |
l = line_calloc(slen); |
if (l == NULL) return(-1); |
l->prev = db->cursor; |
if (db->cursor) { |
l->next = db->cursor->next; |
db->cursor->next = l; |
l->next->prev = l; |
} |
db->cursor = l; |
if (slen > 0) { |
_fmemmove(l->payload, line, slen); |
l->len = slen; |
} |
db->totlines += 1; |
db->curline += 1; |
return(0); |
} |
static void ui_getstring(const char *query, char *s, unsigned short maxlen) { |
unsigned short len = 0; |
unsigned char y, x; |
int k; |
if (maxlen == 0) return; |
maxlen--; /* make room for the nul terminator */ |
y = screenlastrow; |
/* print query string */ |
x = mdr_cout_str(y, 0, query, SCHEME_STBAR3, 40); |
mdr_cout_char_rep(y, x++, ' ', SCHEME_STBAR3, screenw - x); |
for (;;) { |
mdr_cout_locate(y, x + len); |
k = mdr_dos_getkey2(); |
switch (k) { |
case 0x1b: /* ESC */ |
s[0] = 0; |
return; |
case '\r': |
s[len] = 0; |
return; |
case 0x08: /* BKSPC */ |
if (len > 0) { |
len--; |
mdr_cout_char(y, x + len, ' ', SCHEME_STBAR3); |
} |
break; |
default: |
if ((k <= 0xff) && (k >= ' ') && (len < maxlen)) { |
mdr_cout_char(y, x + len, k, SCHEME_STBAR3); |
s[len++] = k; |
} |
} |
} |
} |
/* append a nul-terminated string to line at cursor position */ |
static int line_append(struct file *f, const char far *buf, unsigned short len) { |
if (sizeof(struct line) + f->cursor->len + len < len) goto ERR; /* overflow check */ |
if (curline_resize(f, f->cursor->len + len) != 0) goto ERR; |
_fmemmove(f->cursor->payload + f->cursor->len, buf, len); |
f->cursor->len += len; |
return(0); |
ERR: |
return(-1); |
} |
static void db_rewind(struct file *db) { |
if (db->cursor == NULL) return; |
while (db->cursor->prev) db->cursor = db->cursor->prev; |
db->curline = 0; |
} |
static void ui_statusbar(const struct file *db, unsigned char slotnum) { |
const char *s = svarlang_strid(0); /* ESC=MENU */ |
unsigned short helpcol = screenw - strlen(s); |
unsigned short col; |
/* slot number (guaranteed to be 0-9) */ |
{ |
char slot[4] = "#00"; |
if (slotnum == 9) { |
slot[1] = '1'; |
} else { |
slotnum++; |
slot[2] += slotnum; |
} |
mdr_cout_str(screenlastrow, 0, slot, SCHEME_STBAR2, 3); |
} |
/* fill rest of status bar with background */ |
mdr_cout_char_rep(screenlastrow, 3, ' ', SCHEME_STBAR1, helpcol - 3); |
/* eol type */ |
{ |
const char *eoltype = "CRLF"; |
if (db->lfonly) eoltype += 2; |
mdr_cout_str(screenlastrow, helpcol - 5, eoltype, SCHEME_STBAR1, 5); |
} |
/* line numbers */ |
{ |
unsigned short x; |
unsigned char count = 0; |
col = helpcol - 7; |
x = db->totlines; |
AGAIN: |
do { |
mdr_cout_char(screenlastrow, col--, '0' + (x % 10), SCHEME_STBAR1); |
x /= 10; |
} while (x); |
/* redo same exercise, but printing the current line now */ |
if (count == 0) { |
count = 1; |
mdr_cout_char(screenlastrow, col--, '/', SCHEME_STBAR1); |
x = 1 + db->curline; |
goto AGAIN; |
} |
} |
/* filename and modflag */ |
{ |
const char *fn; |
unsigned short x; |
unsigned short maxfnlen = col - 6; |
if (db->fname[0] == 0) { |
fn = svarlang_str(0, 1); /* "UNTITLED" */ |
} else { |
/* display filename up to maxfnlen chars */ |
fn = db->fname; |
x = strlen(fn); |
if (x > maxfnlen) fn += x - maxfnlen; |
} |
x = mdr_cout_str(screenlastrow, 4, fn, SCHEME_STBAR1, maxfnlen); |
if (db->modflag) mdr_cout_char(screenlastrow, 5 + x, '!', SCHEME_STBAR2); |
} |
mdr_cout_str(screenlastrow, helpcol, s, SCHEME_STBAR2, 40); |
} |
static void ui_msg(const char *msg1, const char *msg2, unsigned char attr) { |
unsigned short x, y, msglen, i; |
unsigned short msg2flag = 0; |
msglen = strlen(msg1); |
if (msg2) { |
msg2flag = 1; |
i = strlen(msg2); |
if (i > msglen) msglen = i; |
} |
y = (screenh - 6) >> 1; |
x = (screenw - msglen - 4) >> 1; |
for (i = y+2+msg2flag; i >= y; i--) mdr_cout_char_rep(i, x, ' ', attr, msglen + 2); |
x++; |
mdr_cout_str(y+1, x, msg1, attr, msglen); |
if (msg2) mdr_cout_str(y+2, x, msg2, attr, msglen); |
if (uidirty.from > y) uidirty.from = y; |
if (uidirty.to < y+4) uidirty.to = y+4; |
} |
static unsigned char ui_confirm_if_unsaved(const struct file *db) { |
unsigned char r = 0; |
if (db->modflag == 0) return(0); |
mdr_cout_cursor_hide(); |
/* if file has been modified then ask for confirmation */ |
ui_msg(svarlang_str(0,4), svarlang_str(0,5), SCHEME_MSG); |
if (mdr_dos_getkey2() != '\r') r = 1; |
mdr_cout_cursor_show(); |
return(r); |
} |
static void ui_refresh(const struct file *db) { |
unsigned char x; |
const struct line far *l; |
unsigned char y = db->cursorposy; |
/* quit early if nothing to refresh */ |
if (uidirty.from == 0xff) return; |
#ifdef DBG_REFRESH |
static char m = 'a'; |
m++; |
if (m > 'z') m = 'a'; |
#endif |
/* rewind cursor line to first line that needs redrawing */ |
for (l = db->cursor; y > uidirty.from; y--) l = l->prev; |
/* iterate over lines and redraw whatever needs to be redrawn */ |
for (; l != NULL; l = l->next, y++) { |
/* skip lines that do not need to be refreshed */ |
if (y < uidirty.from) continue; |
if (y > uidirty.to) break; |
x = 0; |
if (db->xoffset < l->len) { |
unsigned char i, limit; |
if (l->len - db->xoffset < screenw) { |
limit = l->len; |
} else { |
limit = db->xoffset + screenlastcol; |
} |
for (i = db->xoffset; i < limit; i++) mdr_cout_char(y, x++, l->payload[i], SCHEME_TEXT); |
} |
/* write empty spaces until end of line */ |
if (x < screenlastcol) mdr_cout_char_rep(y, x, ' ', SCHEME_TEXT, screenlastcol - x); |
#ifdef DBG_REFRESH |
mdr_cout_char(y, 0, m, SCHEME_STBAR1); |
#endif |
if (y == screenh - 2) break; |
} |
/* fill all lines below if empty (and they need to be redrawn) */ |
if (l == NULL) { |
while ((y < screenlastrow) && (y < uidirty.to)) { |
mdr_cout_char_rep(y++, 0, ' ', SCHEME_TEXT, screenlastcol); |
} |
} |
/* scroll bar */ |
for (y = 0; y < screenlastrow; y++) { |
mdr_cout_char(y, screenlastcol, SCROLL_CURSOR, SCHEME_SCROLL); |
} |
/* scroll cursor */ |
if (db->totlines >= screenh) { |
unsigned short topline = db->curline - db->cursorposy; |
unsigned short col; |
unsigned short totlines = db->totlines - screenh + 1; |
if (db->totlines - screenh > screenh) { |
col = topline / (totlines / screenlastrow); |
} else { |
col = topline * screenlastrow / totlines; |
} |
if (col >= screenlastrow) col = screenh - 2; |
mdr_cout_char(col, screenlastcol, ' ', SCHEME_SCROLL); |
} |
/* clear out the dirty flag */ |
uidirty.from = 0xff; |
} |
static void check_cursor_not_after_eol(struct file *db) { |
if (db->xoffset + db->cursorposx <= db->cursor->len) return; |
if (db->cursor->len < db->xoffset) { |
db->cursorposx = 0; |
db->xoffset = db->cursor->len; |
uidirty.from = 0; |
uidirty.to = 0xff; |
} else { |
db->cursorposx = db->cursor->len - db->xoffset; |
} |
} |
static void cursor_up(struct file *db) { |
if (db->cursor->prev == NULL) return; |
db->curline -= 1; |
db->cursor = db->cursor->prev; |
if (db->cursorposy == 0) { |
uidirty.from = 0; |
uidirty.to = 0xff; |
} else { |
db->cursorposy -= 1; |
} |
} |
static void cursor_eol(struct file *db) { |
/* adjust xoffset to make sure eol is visible on screen */ |
if (db->xoffset > db->cursor->len) { |
db->xoffset = db->cursor->len - 1; |
uidirty.from = 0; |
uidirty.to = 0xff; |
} |
if (db->xoffset + screenlastcol <= db->cursor->len) { |
db->xoffset = db->cursor->len - screenw + 2; |
uidirty.from = 0; |
uidirty.to = 0xff; |
} |
db->cursorposx = db->cursor->len - db->xoffset; |
} |
static void cursor_down(struct file *db) { |
if (db->cursor->next == NULL) return; |
db->curline += 1; |
db->cursor = db->cursor->next; |
if (db->cursorposy < screenh - 2) { |
db->cursorposy += 1; |
} else { |
uidirty.from = 0; |
uidirty.to = 0xff; |
} |
} |
static void cursor_left(struct file *db) { |
if (db->cursorposx > 0) { |
db->cursorposx -= 1; |
} else if (db->xoffset > 0) { |
db->xoffset -= 1; |
uidirty.from = 0; |
uidirty.to = 0xff; |
} else if (db->cursor->prev != NULL) { /* jump to end of line above */ |
cursor_up(db); |
cursor_eol(db); |
} |
} |
static void cursor_home(struct file *db) { |
db->cursorposx = 0; |
if (db->xoffset != 0) { |
db->xoffset = 0; |
uidirty.from = 0; |
uidirty.to = 0xff; |
} |
} |
static void cursor_right(struct file *db) { |
if (db->cursor->len > db->xoffset + db->cursorposx) { |
if (db->cursorposx < screenw - 2) { |
db->cursorposx += 1; |
} else { |
db->xoffset += 1; |
uidirty.from = 0; |
uidirty.to = 0xff; |
} |
} else if (db->cursor->next != NULL) { /* jump to start of next line */ |
cursor_down(db); |
cursor_home(db); |
} |
} |
static void del(struct file *db) { |
if (db->cursorposx + db->xoffset < db->cursor->len) { |
_fmemmove(db->cursor->payload + db->cursorposx + db->xoffset, db->cursor->payload + db->cursorposx + db->xoffset + 1, db->cursor->len - db->cursorposx - db->xoffset); |
db->cursor->len -= 1; /* do this AFTER memmove so the copy includes the nul terminator */ |
uidirty.from = db->cursorposy; |
uidirty.to = db->cursorposy; |
db->modflag = 1; |
} else if (db->cursor->next != NULL) { /* cursor is at end of line: merge current line with next one (if there is a next one) */ |
struct line far *nextline = db->cursor->next; |
if (db->cursor->next->len > 0) { |
if (curline_resize(db, db->cursor->len + db->cursor->next->len + 1) == 0) { |
_fmemmove(db->cursor->payload + db->cursor->len, db->cursor->next->payload, db->cursor->next->len + 1); |
db->cursor->len += db->cursor->next->len; |
} |
} |
db->cursor->next = db->cursor->next->next; |
db->cursor->next->prev = db->cursor; |
line_free(nextline); |
uidirty.from = db->cursorposy; |
uidirty.to = 0xff; |
db->totlines -= 1; |
db->modflag = 1; |
} |
} |
static void bkspc(struct file *db) { |
/* backspace is basically "left + del", not applicable only if cursor is on 1st byte of the file */ |
if ((db->cursorposx + db->xoffset == 0) && (db->cursor->prev == NULL)) return; |
cursor_left(db); |
del(db); |
} |
#define LOADFILE_FILENOTFOUND 2 |
/* returns 0 on success, 1 on file not found, 2 on other error */ |
static unsigned char loadfile(struct file *db, const char *fname) { |
char buff[512]; /* read one entire sector at a time (faster) */ |
char *buffptr; |
unsigned int len, llen; |
int fd; |
unsigned char eolfound; |
unsigned char err = 0; |
/* free the entire linked list of lines */ |
db_rewind(db); |
while (db->cursor) { |
struct line far *victim; |
victim = db->cursor; |
db->cursor = db->cursor->next; |
line_free(victim); |
} |
/* zero out the struct */ |
bzero(db, sizeof(struct file)); |
/* start by adding an empty line */ |
if (line_add(db, NULL, 0) != 0) return(2); |
if (fname == NULL) goto SKIPLOADING; |
mdr_dos_truename(db->fname, fname); |
err = _dos_open(fname, O_RDONLY, &fd); |
if (err != 0) goto SKIPLOADING; |
db->lfonly = 1; |
for (eolfound = 0;;) { |
unsigned short consumedbytes; |
if ((_dos_read(fd, buff, sizeof(buff), &len) != 0) || (len == 0)) break; |
buffptr = buff; |
FINDLINE: |
/* look for nearest \n (also expand tabs) */ |
for (consumedbytes = 0;; consumedbytes++) { |
if (buffptr[consumedbytes] == '\t') { |
llen = consumedbytes; |
break; |
} |
if (consumedbytes == len) { |
llen = consumedbytes; |
break; |
} |
if (buffptr[consumedbytes] == '\r') { |
llen = consumedbytes; |
consumedbytes++; |
db->lfonly = 0; |
break; |
} |
if (buffptr[consumedbytes] == '\n') { |
eolfound = 1; |
llen = consumedbytes; |
consumedbytes++; |
break; |
} |
} |
/* consumedbytes is the amount of bytes processed from buffptr, |
* llen is the length of line's payload (without its line terminator) */ |
/* append content, if line is non-empty */ |
if ((llen > 0) && (line_append(db, buffptr, llen) != 0)) { |
goto IOERR; |
} |
/* allocate the next line if current line ended */ |
if (eolfound) { |
if (line_add(db, NULL, 0) != 0) { |
goto IOERR; |
} |
eolfound = 0; |
} |
/* append 8 spaces if tab char found */ |
if ((consumedbytes < len) && (buffptr[consumedbytes] == '\t') && (glob_tablessmode == 0)) { |
consumedbytes++; |
if (line_append(db, " ", 8) != 0) { |
goto IOERR; |
} |
} |
/* anything left? process the buffer leftover again */ |
if (consumedbytes < len) { |
len -= consumedbytes; |
buffptr += consumedbytes; |
goto FINDLINE; |
} |
} |
_dos_close(fd); |
SKIPLOADING: |
/* rewind cursor to top of file because it has been used by line_add() */ |
db_rewind(db); |
return(err); |
IOERR: |
_dos_close(fd); |
return(1); |
} |
/* a custom argv-parsing routine that looks directly inside the PSP, avoids the need |
* of argc and argv, saves some 330 bytes of binary size |
* returns non-zero on error */ |
static int parseargv(struct file *dbarr) { |
char *tail = (void *)0x81; /* THIS WORKS ONLY IN SMALL MEMORY MODEL */ |
unsigned short count = 0; |
char *arg; |
unsigned short lastarg = 0; |
unsigned char err; |
while (!lastarg) { |
/* jump to nearest arg */ |
while (*tail == ' ') { |
*tail = 0; |
tail++; |
} |
if (*tail == '\r') { |
*tail = 0; |
break; |
} |
arg = tail; |
/* jump to next delimiter */ |
while ((*tail != ' ') && (*tail != '\r')) tail++; |
/* if \r then remember this is the last arg */ |
if (*tail == '\r') lastarg = 1; |
*tail = 0; |
tail++; |
/* look at the arg now */ |
if (*arg == '/') { |
if (arg[1] == 't') { /* /t = do not expand tabs */ |
glob_tablessmode = 1; |
} else if (arg[1] == 'm') { /* /m = force mono mode */ |
glob_monomode = 1; |
} else { /* help screen */ |
mdr_coutraw_str(svarlang_str(1,3)); /* Sved, the SvarDOS editor */ |
mdr_coutraw_str(" ["); |
mdr_coutraw_str(svarlang_str(1,4)); /* ver */ |
mdr_coutraw_puts(" " PVER "]"); |
mdr_coutraw_puts("Copyright (C) " PDATE " Mateusz Viste"); |
mdr_coutraw_crlf(); |
mdr_coutraw_str("sved [/m] [/t] "); |
mdr_coutraw_puts(svarlang_str(1,1)); /* args syntax */ |
mdr_coutraw_crlf(); |
mdr_coutraw_puts(svarlang_str(1,10)); /* /m */ |
mdr_coutraw_puts(svarlang_str(1,11)); /* /t */ |
return(-1); |
} |
continue; |
} |
/* looks to be a filename */ |
if (count == 10) { |
mdr_coutraw_puts(svarlang_str(0,12)); /* too many files */ |
return(-1); |
} |
/* try loading it */ |
mdr_coutraw_str(svarlang_str(1,2)); |
mdr_coutraw_char(' '); |
mdr_coutraw_puts(arg); |
err = loadfile(&(dbarr[count]), arg); |
if (err) { |
if (err == LOADFILE_FILENOTFOUND) { /* file not found */ |
if ((count == 0) && (lastarg != 0)) { /* a 'file not found' is fine if only one file was given */ |
err = 0; |
} else { |
err = 11; |
} |
} else { /* general error */ |
err = 10; |
} |
if (err) { |
mdr_coutraw_puts(svarlang_str(0,err)); |
return(-1); |
} |
} |
count++; |
} |
return(0); |
} |
static int savefile(const struct file *db, const char *saveas) { |
int fd = 0; |
const struct line far *l; |
unsigned int bytes; |
unsigned char eollen = 2; |
const unsigned char *eolbuf = "\r\n"; |
int errflag = 0; |
/* if filename not overloaded then use the fname in db */ |
if (saveas == NULL) saveas = db->fname; |
_asm { |
push ax |
push cx |
push dx |
mov ah, 0x3C /* create or truncate file */ |
xor cx, cx /* file attributes */ |
mov dx, saveas /* works only in SMALL/TINY mode */ |
int 0x21 |
jnc DONE |
mov errflag, ax |
DONE: |
mov fd, ax |
pop dx |
pop cx |
pop ax |
} |
if (errflag != 0) return(-1); |
l = db->cursor; |
while (l->prev) l = l->prev; |
/* preset line terminators */ |
if (db->lfonly) { |
eolbuf++; |
eollen--; |
} |
while (l) { |
/* do not write the last empty line, it is only useful for edition */ |
if (l->len != 0) { |
errflag |= _dos_write(fd, l->payload, l->len, &bytes); |
} else if (l->next == NULL) { |
break; |
} |
errflag |= _dos_write(fd, eolbuf, eollen, &bytes); |
l = l->next; |
} |
errflag |= _dos_close(fd); |
return(errflag); |
} |
static void insert_in_line(struct file *db, const char *databuf, unsigned short len) { |
if (curline_resize(db, db->cursor->len + len) == 0) { |
unsigned short off = db->xoffset + db->cursorposx; |
db->modflag = 1; |
_fmemmove(db->cursor->payload + off + len, db->cursor->payload + off, db->cursor->len - off + 1); |
db->cursor->len += len; |
uidirty.from = db->cursorposy; |
uidirty.to = db->cursorposy; |
while (len--) { |
db->cursor->payload[off++] = *databuf; |
databuf++; |
cursor_right(db); |
} |
} |
} |
/* recompute db->curline by counting nodes in linked list */ |
static void recompute_curline(struct file *db) { |
const struct line far *l = db->cursor; |
db->curline = 0; |
while (l->prev != NULL) { |
db->curline += 1; |
l = l->prev; |
} |
} |
enum MENU_ACTION { |
MENU_NONE = 0, |
MENU_OPEN = 1, |
MENU_SAVE = 2, |
MENU_SAVEAS = 3, |
MENU_CLOSE = 4, |
MENU_CHGEOL = 5, |
MENU_QUIT = 6 |
}; |
static enum MENU_ACTION ui_menu(void) { |
unsigned short i, curchoice, attr, x, slen; |
unsigned short xorigin, yorigin; |
/* find out the longest string */ |
slen = 0; |
for (i = MENU_OPEN; i <= MENU_QUIT; i++) { |
x = strlen(svarlang_str(8, i)); |
if (x > slen) slen = x; |
} |
/* calculate where to draw the menu on screen */ |
xorigin = (screenw - (slen + 5)) / 2; |
yorigin = (screenh - (MENU_QUIT - MENU_OPEN + 6)) / 2; |
/* */ |
uidirty.from = yorigin; |
uidirty.to = 0xff; |
uidirty.statusbar = 1; |
/* hide the cursor */ |
mdr_cout_cursor_hide(); |
curchoice = MENU_OPEN; |
for (;;) { |
/* render menu */ |
for (i = MENU_NONE; i <= MENU_QUIT + 1; i++) { |
mdr_cout_char_rep(yorigin + i, xorigin, ' ', SCHEME_MENU, slen+4); |
if (i == curchoice) { |
attr = SCHEME_MENU_CUR; |
mdr_cout_char_rep(yorigin + i, xorigin + 1, ' ', SCHEME_MENU_SEL, slen + 2); |
} else { |
attr = SCHEME_MENU; |
} |
mdr_cout_str(yorigin + i, xorigin + 2, svarlang_str(8, i), attr, slen); |
} |
/* wait for key */ |
switch (mdr_dos_getkey2()) { |
case 0x150: /* down */ |
if (curchoice == MENU_QUIT) { |
curchoice = MENU_OPEN; |
} else { |
curchoice++; |
} |
break; |
case 0x148: /* up */ |
if (curchoice == MENU_OPEN) { |
curchoice = MENU_QUIT; |
} else { |
curchoice--; |
} |
break; |
default: |
curchoice = MENU_NONE; |
/* FALLTHRU */ |
case '\r': /* ENTER */ |
mdr_cout_cursor_show(); |
return(curchoice); |
} |
} |
} |
static struct file *select_slot(struct file *dbarr, unsigned char curfile) { |
uidirty.from = 0; |
uidirty.to = 0xff; |
uidirty.statusbar = 1; |
dbarr = &(dbarr[curfile]); |
/* force redraw now, because the main() routine might not if this is exit |
* time and we want to show the user which file has unsaved changes */ |
ui_statusbar(dbarr, curfile); |
ui_refresh(dbarr); |
return(dbarr); |
} |
/* main returns nothing, ie. sved always exits with a zero exit code |
* (this saves 20 bytes of executable footprint) */ |
void main(void) { |
static struct file dbarr[10]; |
unsigned char curfile; |
struct file *db = dbarr; /* visible file is the first slot by default */ |
struct line far *clipboard = NULL; |
unsigned char original_breakflag; |
{ /* load NLS resource */ |
unsigned short i = 0; |
const char far *selfptr; |
char self[128], lang[8]; |
selfptr = mdr_dos_selfexe(); |
if (selfptr != NULL) { |
do { |
self[i] = selfptr[i]; |
} while (self[i++] != 0); |
svarlang_autoload_exepath(self, mdr_dos_getenv(lang, "LANG", sizeof(lang))); |
} |
} |
/* preload all slots with empty files */ |
for (curfile = 9;; curfile--) { |
loadfile(&(dbarr[curfile]), NULL); |
if (curfile == 0) break; |
} |
/* parse argv (and load files, if any passed on) */ |
if (parseargv(dbarr) != 0) return; |
if ((mdr_cout_init(&screenw, &screenh) != 0) && (glob_monomode == 0)) { |
/* load color scheme if mdr_cout_init returns a color flag */ |
SCHEME_TEXT = 0x17; |
SCHEME_MENU = 0x70; |
SCHEME_MENU_CUR = 0x6f; |
SCHEME_MENU_SEL = 0x66; |
SCHEME_STBAR1 = 0x70; |
SCHEME_STBAR2 = 0x78; |
SCHEME_STBAR3 = 0x3f; |
SCHEME_SCROLL = 0x70; |
SCHEME_MSG = 0x6f; |
SCHEME_ERR = 0x4f; |
} |
screenlastrow = screenh - 1; |
screenlastcol = screenw - 1; |
/* instruct DOS to stop detecting CTRL+C because user needs it for |
* copy/paste operations. also remember the original status of the BREAK |
* flag so I can restore it as it was before quitting. */ |
original_breakflag = mdr_dos_ctrlc_disable(); |
for (;;) { |
int k; |
/* add an extra empty line if cursor is on last line and this line is not empty */ |
if ((db->cursor->next == NULL) && (db->cursor->len != 0)) { |
if (line_add(db, NULL, 0) == 0) { |
db->cursor = db->cursor->prev; /* line_add() changes the cursor pointer */ |
db->curline -= 1; |
} |
} |
check_cursor_not_after_eol(db); |
mdr_cout_locate(db->cursorposy, db->cursorposx); |
ui_refresh(db); |
if ((uidirty.statusbar != 0) || (db->modflagprev != db->modflag) || (db->curline_prev != db->curline)) { |
ui_statusbar(db, curfile); |
uidirty.statusbar = 0; |
db->modflagprev = db->modflag; |
db->curline_prev = db->curline; |
} |
#ifdef DBG_LINENUM |
{ |
char ddd[10]; |
db->curline += 1; |
ddd[0] = '0' + db->curline / 100; |
ddd[1] = '0' + (db->curline % 100) / 10; |
ddd[2] = '0' + (db->curline % 10); |
db->curline -= 1; |
ddd[3] = '/'; |
ddd[4] = '0' + db->totlines / 100; |
ddd[5] = '0' + (db->totlines % 100) / 10; |
ddd[6] = '0' + (db->totlines % 10); |
ddd[7] = 0; |
mdr_cout_str(screenh - 1, 40, ddd, SCHEME_STBAR1, sizeof(ddd)); |
} |
#endif |
k = mdr_dos_getkey2(); |
if (k == 0x150) { /* down */ |
cursor_down(db); |
} else if (k == 0x148) { /* up */ |
cursor_up(db); |
} else if (k == 0x14D) { /* right */ |
cursor_right(db); |
} else if (k == 0x14B) { /* left */ |
cursor_left(db); |
} else if (k == 0x149) { /* pgup */ |
unsigned char dist = db->cursorposy + screenh - 1; |
while ((dist != 0) && (db->cursor->prev != NULL)) { |
db->cursor = db->cursor->prev; |
dist--; |
} |
if (dist != 0) { |
db->cursorposy = 0; |
db->cursorposx = 0; |
} else { |
dist = db->cursorposy; |
while ((dist--) && (db->cursor->next)) db->cursor = db->cursor->next; |
} |
uidirty.from = 0; |
uidirty.to = 0xff; |
recompute_curline(db); |
} else if (k == 0x151) { /* pgdown */ |
unsigned char dist = screenh + screenh - db->cursorposy - 3; |
while ((dist != 0) && (db->cursor->next != NULL)) { |
db->cursor = db->cursor->next; |
dist--; |
} |
if (dist != 0) { |
db->cursorposy = screenh - 2; |
if (db->totlines <= db->cursorposy) db->cursorposy = db->totlines - 1; |
db->cursorposx = 0; |
} else { |
dist = screenh - 2 - db->cursorposy; |
while ((dist--) && (db->cursor->prev)) db->cursor = db->cursor->prev; |
} |
uidirty.from = 0; |
uidirty.to = 0xff; |
recompute_curline(db); |
} else if (k == 0x147) { /* home */ |
cursor_home(db); |
} else if (k == 0x14F) { /* end */ |
cursor_eol(db); |
} else if (k == 0x1B) { /* ESC */ |
int quitnow = 0; |
char fname[64]; |
int saveflag = 0; |
enum MENU_ACTION ui_action; |
/* collect the exact menu action and clear the screen */ |
ui_action = ui_menu(); |
ui_refresh(db); |
switch (ui_action) { |
case MENU_NONE: |
break; |
case MENU_OPEN: |
/* display a warning if unsaved changes are pending */ |
if (db->modflag != 0) ui_msg(svarlang_str(0,4), svarlang_str(0,8), SCHEME_MSG); |
/* ask for filename */ |
ui_getstring(svarlang_str(0,7), fname, sizeof(fname)); |
if (fname[0] != 0) { |
unsigned char err; |
err = loadfile(db, fname); |
if (err != 0) { |
if (err == LOADFILE_FILENOTFOUND) { |
ui_msg(svarlang_str(0,11), NULL, SCHEME_ERR); /* file not found */ |
} else { |
ui_msg(svarlang_str(0,10), NULL, SCHEME_ERR); /* ERROR */ |
} |
mdr_bios_tickswait(44); /* 3s */ |
loadfile(db, NULL); |
} |
} |
uidirty.from = 0; |
uidirty.to = 0xff; |
uidirty.statusbar = 1; |
break; |
case MENU_SAVEAS: |
saveflag = 1; |
/* FALLTHRU */ |
case MENU_SAVE: |
if ((saveflag != 0) || (db->fname[0] == 0)) { /* save as... */ |
ui_getstring(svarlang_str(0,6), fname, sizeof(fname)); |
if (*fname == 0) break; |
saveflag = savefile(db, fname); |
if (saveflag == 0) mdr_dos_truename(db->fname, fname); |
} else { |
saveflag = savefile(db, NULL); |
} |
mdr_cout_cursor_hide(); |
if (saveflag == 0) { |
db->modflag = 0; |
ui_msg(svarlang_str(0, 2), NULL, SCHEME_MSG); |
mdr_bios_tickswait(11); /* 11 ticks is about 600 ms */ |
} else { |
ui_msg(svarlang_str(0, 10), NULL, SCHEME_ERR); |
mdr_bios_tickswait(36); /* 2s */ |
} |
mdr_cout_cursor_show(); |
break; |
case MENU_CLOSE: |
if (ui_confirm_if_unsaved(db) == 0) { |
loadfile(db, NULL); |
} |
uidirty.from = 0; |
uidirty.to = 0xff; |
uidirty.statusbar = 1; |
break; |
case MENU_CHGEOL: |
db->modflag = 1; |
db->lfonly ^= 1; |
break; |
case MENU_QUIT: |
quitnow = 1; |
for (curfile = 0; curfile < 10; curfile++) { |
if (dbarr[curfile].modflag) { |
db = select_slot(dbarr, curfile); |
if (ui_confirm_if_unsaved(db) != 0) { |
quitnow = 0; |
break; |
} |
} |
} |
break; |
} |
if (quitnow) break; |
} else if (k == 0x0D) { /* ENTER */ |
unsigned short off = db->xoffset + db->cursorposx; |
/* add a new line */ |
if (line_add(db, db->cursor->payload + off, db->cursor->len - off) == 0) { |
db->modflag = 1; |
db->cursor = db->cursor->prev; /* back to original line */ |
db->curline -= 1; |
/* trim the line above */ |
db->cursor->len = off; |
/* move cursor to the (new) line below */ |
uidirty.from = db->cursorposy; |
uidirty.to = 0xff; |
cursor_down(db); |
cursor_home(db); |
} else { |
/* ERROR: OUT OF MEMORY */ |
} |
} else if (k == 0x153) { /* DEL */ |
del(db); |
} else if (k == 0x008) { /* BKSPC */ |
bkspc(db); |
} else if ((k >= 0x20) && (k <= 0xff)) { /* "normal" character */ |
char c = k; |
insert_in_line(db, &c, 1); |
} else if (k == 0x009) { /* TAB */ |
if (glob_tablessmode == 0) { |
insert_in_line(db, " ", 8); |
} else { |
insert_in_line(db, "\t", 1); |
} |
} else if ((k >= 0x13b) && (k <= 0x144)) { /* F1..F10 */ |
curfile = k - 0x13b; |
db = select_slot(dbarr, curfile); |
} else if (k == 0x174) { /* CTRL+ArrRight - jump to next word */ |
/* if currently cursor is on a non-space, then fast-forward to nearest space or EOL */ |
for (;;) { |
if (db->xoffset + db->cursorposx == db->cursor->len) break; |
if (db->cursor->payload[db->xoffset + db->cursorposx] == ' ') break; |
cursor_right(db); |
} |
/* now skip to next non-space or end of file */ |
for (;;) { |
cursor_right(db); |
if (db->cursor->payload[db->xoffset + db->cursorposx] != ' ') break; |
if ((db->cursor->next == NULL) && (db->cursorposx + db->xoffset == db->cursor->len)) break; |
} |
} else if (k == 0x173) { /* CTRL+ArrLeft - jump to prev word */ |
cursor_left(db); |
/* if currently cursor is on a space, then fast-forward to nearest non-space or start of line */ |
for (;;) { |
if ((db->xoffset == 0) && (db->cursorposx == 0)) break; |
if (db->cursor->payload[db->xoffset + db->cursorposx] != ' ') break; |
cursor_left(db); |
} |
/* now skip to next space or start of file */ |
for (;;) { |
cursor_left(db); |
if (db->cursor->payload[db->xoffset + db->cursorposx] == ' ') { |
cursor_right(db); |
break; |
} |
if ((db->cursorposx == 0) && (db->xoffset == 0)) break; |
} |
} else if ((k == 0x003) || (k == 0x018)) { /* CTRL+C or CTRL+X */ |
/* free clipboard if anything in it */ |
if (clipboard != NULL) line_free(clipboard); |
/* copy cursor line to clipboard */ |
clipboard = line_calloc(db->cursor->len); |
if (clipboard == NULL) { |
ui_msg(svarlang_str(0, 10), NULL, SCHEME_ERR); /* ERROR */ |
mdr_bios_tickswait(18); /* 1s */ |
} else { |
mdr_cout_char_rep(db->cursorposy, 0, ' ', ((SCHEME_TEXT >> 4) | (SCHEME_TEXT << 4)) & 0xff, screenlastcol); |
uidirty.from = db->cursorposy; |
uidirty.to = db->cursorposy; |
if (db->cursor->len != 0) { |
_fmemmove(clipboard->payload, db->cursor->payload, db->cursor->len); |
clipboard->len = db->cursor->len; |
} |
mdr_bios_tickswait(2); /* ca 100ms */ |
/* if this is about cutting the line (CTRL+X) then delete cur line */ |
if ((k == 0x018) && ((db->cursor->next != NULL) || (db->cursor->prev != NULL))) { |
if (db->cursor->next) db->cursor->next->prev = db->cursor->prev; |
if (db->cursor->prev) db->cursor->prev->next = db->cursor->next; |
clipboard->prev = db->cursor; |
if (db->cursor->next) { |
db->cursor = db->cursor->next; |
} else { |
cursor_up(db); |
} |
line_free(clipboard->prev); |
db->totlines -= 1; |
uidirty.from = 0; |
uidirty.to = 0xff; |
recompute_curline(db); |
} |
} |
} else if ((k == 0x016) && (clipboard != NULL)) { /* CTRL+V */ |
if (line_add(db, clipboard->payload, clipboard->len) != 0) { |
ui_msg(svarlang_str(0, 10), NULL, SCHEME_ERR); /* ERROR */ |
mdr_bios_tickswait(18); /* 1s */ |
} else { |
/* rewire the linked list so the new line is on top of the previous one */ |
clipboard->prev = db->cursor->prev; |
/* remove prev node from list */ |
db->cursor->prev = db->cursor->prev->prev; |
if (db->cursor->prev != NULL) db->cursor->prev->next = db->cursor; |
/* insert the node after cursor now */ |
clipboard->prev->next = db->cursor->next; |
if (db->cursor->next != NULL) db->cursor->next->prev = clipboard->prev; |
clipboard->prev->prev = db->cursor; |
db->cursor->next = clipboard->prev; |
cursor_down(db); |
} |
uidirty.from = 0; |
uidirty.to = 0xff; |
recompute_curline(db); |
#ifdef DBG_UNHKEYS |
} else { /* UNHANDLED KEY - TODO IGNORE THIS IN PRODUCTION RELEASE */ |
char buff[4]; |
const char *HEX = "0123456789ABCDEF"; |
buff[0] = HEX[(k >> 8) & 15]; |
buff[1] = HEX[(k >> 4) & 15]; |
buff[2] = HEX[k & 15]; |
mdr_cout_str(screenh - 1, 0, "UNHANDLED KEY: 0x", SCHEME_STBAR1, 17); |
mdr_cout_str(screenh - 1, 17, buff, SCHEME_STBAR1, 3); |
mdr_dos_getkey2(); |
break; |
#endif |
} |
} |
mdr_cout_close(); |
/* restore the DOS BREAK flag if it was originally set */ |
if (original_breakflag != 0) mdr_dos_ctrlc_enable(); |
/* no need to free memory, DOS will do it for me */ |
return; |
} |
/sved/tags/2023.3/sved.lng |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/sved/tags/2023.3/sved.txt |
---|
0,0 → 1,111 |
THE SVARDOS EDITOR |
### WHAT IT IS ############################################################### |
The SvarDOS editor (SVED) is designed for basic editing of configuration files |
and such. It is NOT meant to be a full-featured text editor. On the pro side, |
it has a low memory footprint and is only a couple kilobytes big, which makes |
it a good fit for bootdisks and systems with extremely limited resources. |
- runs comfortably on a 8086-class PC with 256 KiB of RAM |
- auto-detects color and monochrome video modes |
- supports unusual text modes like 80x43, 80x50, 132x60, 40x25... |
- multilingual UI |
- only 7 KiB of disk footprint |
- screen estate dedicated to text (no stupid frames, menus and such) |
- loads files larger than 64 KiB |
- no line length limit |
- can load up to 10 files simultaneously |
- COPY/CUT/PASTE between files |
- handles CR/LF and LF line endings and can convert between them |
What SVED does NOT have: |
- mouse support |
- an integrated file browser |
- undo |
- search |
- ... |
### USAGE AND KEY BINDINGS ################################################### |
Navigation within the text file is achieved through the usual, standard keys: |
- up, down, right and left arrows |
- PageUp / PageDown |
- Home / End |
On top of these, the following key bindings are available: |
ESC = access the program's menu |
CTRL+RIGHT = jump to next word |
CTRL+LEFT = jump to previous word |
CTRL+C = copy the current line to clipboard |
CTRL+X = cut the current line and move it to clipboard |
CTRL+V = paste the clipboard content to current location |
SVED can load up to 10 files simultaneously. To switch from one file to |
another use the F1..F10 function keys (F1 = file 1, F2 = file 2, etc). |
### MULTILINGUAL SUPPORT ##################################################### |
The LNG file contains non-english strings. It should be placed in the same |
directory where the program's executable resides. The UI language is |
controlled by the LANG environment variable, for example SET LANG=PL would |
make it display polish strings. |
Following LANG settings are supported: EN FR PL RU TR. |
If you rename the SVED.COM executable (for example to EDIT.COM), then you need |
to rename the LNG file accordingly (for example to EDIT.LNG). |
You can safely delete the LNG file if you are happy with an english-only UI |
and wish to free a bit of disk space. |
### CHANGELOG ################################################################ |
2023.3 [13 Aug 2023] |
- added turkish translation, courtesy of Berki Yenigun |
2023.2 [07 Aug 2023] |
- added french translations |
- fixed saving to new file when filename was passed on command-line |
2023.1 [07 Aug 2023] |
- fixed onscreen garbage when opening a non-existent file (sved notexist.txt) |
- abort with error when an invalid filename is given as argument (sved *) |
2023.0 [07 Aug 2023] |
- initial release |
### LICENSE ################################################################## |
The SvarDOS editor (SVED) is released under the terms of the MIT license. |
Copyright (C) 2023 Mateusz Viste |
Permission is hereby granted, free of charge, to any person obtaining a copy |
of this software and associated documentation files (the "Software"), to deal |
in the Software without restriction, including without limitation the rights |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the Software is |
furnished to do so, subject to the following conditions: |
The above copyright notice and this permission notice shall be included in |
all copies or substantial portions of the Software. |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
SOFTWARE. |
###################################################################### EOF ### |