Subversion Repositories SvarDOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1473 → Rev 1474

/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 ###