/sved/tags/2024.1/deflang.c |
---|
0,0 → 1,63 |
/* THIS FILE HAS BEEN GENERATED BY TLUMACZ (PART OF THE SVARLANG LIBRARY) */ |
const unsigned short svarlang_memsz = 423u; |
const unsigned short svarlang_string_count = 24u; |
char svarlang_mem[423] = { |
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,0x21,0x00, |
0x45,0x4e,0x54,0x45,0x52,0x20,0x3d,0x20,0x63,0x6f,0x6e,0x66,0x69,0x72,0x6d,0x00, |
0x53,0x61,0x76,0x65,0x20,0x61,0x73,0x3a,0x00, |
0x4c,0x6f,0x61,0x64,0x3a,0x00, |
0x45,0x53,0x43,0x20,0x3d,0x20,0x63,0x61,0x6e,0x63,0x65,0x6c,0x00, |
0x53,0x50,0x41,0x43,0x45,0x20,0x3d,0x20,0x73,0x61,0x76,0x65,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[48] = { |
0x0000,0x0000, |
0x0001,0x0009, |
0x0002,0x0012, |
0x0004,0x0018, |
0x0005,0x0036, |
0x0006,0x0046, |
0x0007,0x004f, |
0x0008,0x0055, |
0x0009,0x0062, |
0x000a,0x006f, |
0x000b,0x0075, |
0x000c,0x0084, |
0x0101,0x0093, |
0x0102,0x00b0, |
0x0103,0x00b8, |
0x0104,0x00d1, |
0x010a,0x00d5, |
0x010b,0x00ef, |
0x0801,0x0110, |
0x0802,0x011a, |
0x0803,0x011f, |
0x0804,0x012a, |
0x0805,0x0135, |
0x0806,0x0140 |
}; |
/sved/tags/2024.1/makefile |
---|
0,0 → 1,64 |
# |
# sved's makefile -- requires Open Watcom 1.9 (wmake) |
# Copyright (C) 2023-2024 Mateusz Viste |
# |
# usage: |
# wmake builds the sved.com binary |
# wmake release builds distribuable packages (svp, zip, sources...) |
CC = wcc |
CFLAGS = -0 -ms -zl -os -wx -we -d0 -bt=dos -I=mdr\inc |
CFLAGS += -s |
PVER = 2024.1 |
all: sved.com |
sved.com: sved.obj deflang.obj |
wasm -DSTACKSIZE=1024 -DNOSTACKCHECK startup.asm |
wlink @sved.lnk |
upx -9 --8086 sved.com |
deflang.obj: NLS\*_UTF8.TXT |
cd nls |
regen.bat |
cd .. |
$(CC) $(CFLAGS) $*.C |
.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 |
echo @ECHO There is no EDIT on this system. Use SVED instead.> bin\edit.bat |
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 *.asm *.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/2024.1/mdr/history.txt |
---|
0,0 → 1,39 |
version xxxx (xx xxx xxxx) |
- added the OPL driver (Adlib-style OPL2 FM synth) along with IMF playback |
- 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() |
- added mdr_bios_ticks() |
- renamed keyb_getkey() to mdr_dos_getkey() |
- renamed keyb_flush() to mdr_dos_flushkeyb() |
- renamed all timer_ functions to mdr_timer_ |
- 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 |
- renamed pcx_anal() and pcx_load() to mdr_pcx_anal() and mdr_pcx_load() |
- added pcx_loadrow(): loads PCX data row by row (useful on PCX files > 64K) |
- replaced pcx_convto8bpp() by mdr_pcx_to8bpp() |
- vid12_putscanline() optimizations: 22% faster |
- renamed all the mouse_ functions to mdr_mouse_ |
- improved mdr_cout_cursor_hide() so it works well on VirtualBox |
- added mdr_mouse_setcursor() |
- added vid12_waitblank() |
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/2024.1/mdr/inc/mdr/bios.h |
---|
0,0 → 1,39 |
/* |
* 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); |
/* returns the current BIOS tick counter (18.2 Hz, 1 tick is roughly 55ms, an |
* hour has 65543 ticks). works on IBM PC, XT, AT - ie. it's always safe */ |
unsigned short mdr_bios_ticks(void); |
#endif |
/sved/tags/2024.1/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/2024.1/mdr/inc/mdr/dos.h |
---|
0,0 → 1,114 |
/* |
* 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. |
* This function requires a 3.x+ DOS kernel. |
* name is simply copied to result on error. */ |
void mdr_dos_truename(char *result, const char *name); |
#endif |
/sved/tags/2024.1/mdr/inc/mdr/mouse.h |
---|
0,0 → 1,60 |
/* |
* 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-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_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. |
* after initialization the mouse cursor is hidden, use mdr_mouse_show() to |
* make it visible. */ |
int mdr_mouse_init(void); |
/* shows the mouse pointer */ |
void mdr_mouse_show(void); |
/* hides the mouse pointer */ |
void mdr_mouse_hide(void); |
/* get x/y coordinates of the mouse, and returns a bitfield with state of buttons */ |
int mdr_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 mdr_mouse_fetchrelease(int *x, int *y); |
/* set graphic pointer shape. icon is 64-bytes long, two sets of 32. each set |
* of 32 bytes is organized as a 16x16 bitmap, ie. 16 rows of 16-bit values. |
* a) the first set of 16 shorts defines the background mask - that is, the |
* background will show through wherever there is a 1-bit in that data. |
* b) the second set defines the "XOR mask" - that is, the pixels matching the |
* 1-bit in this data set are toggled. |
* hotspotx and hotspoty define respectively the horizontal and vertical hot |
* spot of the pointer (default being [0,0], that is the top left corner). */ |
void mdr_mouse_setcursor(const unsigned short *icon, unsigned char hotspotx, unsigned char hotspoty); |
#endif |
/sved/tags/2024.1/mdr/inc/mdr/opl.h |
---|
0,0 → 1,241 |
/* |
* Library to access OPL2/OPL3 hardware (YM3812 / YMF262) |
* |
* 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-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_opl_h |
#define mdr_opl_h |
struct mdr_opl_timbre { |
unsigned char mod_ws, car_ws; /* waveform select (0-4), reg Exh */ |
unsigned char mod_sr, car_sr; /* sustain/release, reg 8xh */ |
unsigned char mod_ad, car_ad; /* attack/decay, reg 6xh */ |
unsigned char mod_20, car_20; /* tremolo/vibrato/sustain..., reg 2xh */ |
unsigned char mod_40, car_40; /* reg 4xh */ |
unsigned char feedconn; |
}; |
struct mdr_opl_timbretemplate { |
struct { |
unsigned char ws; /* waveform select 0..3 */ |
unsigned char sustlev; /* sustain level 0..15 */ |
unsigned char release; /* release level 0..15 */ |
unsigned char attack; /* attack rate 0..15 */ |
unsigned char decay; /* decay rate 0..15 */ |
unsigned char tremolo; /* tremolo flag 0..1 */ |
unsigned char vibrato; /* vibrato flag 0..1 */ |
unsigned char sustain; /* sustain flag 0..1 */ |
unsigned char ksr; /* KSR (envelope scaling) flag 0..1 */ |
unsigned char mult; /* frequency multiplication factor 0..15 */ |
unsigned char ksl; /* Key Scale Level 0..3 */ |
unsigned char outlev; /* output level 0..63 */ |
} carrier; |
struct { |
unsigned char ws; /* waveform select 0..3 */ |
unsigned char sustlev; /* sustain level 0..15 */ |
unsigned char release; /* release level 0..15 */ |
unsigned char attack; /* attack rate 0..15 */ |
unsigned char decay; /* decay rate 0..15 */ |
unsigned char tremolo; /* tremolo flag 0..1 */ |
unsigned char vibrato; /* vibrato flag 0..1 */ |
unsigned char sustain; /* sustain flag 0..1 */ |
unsigned char ksr; /* KSR (envelope scaling) flag 0..1 */ |
unsigned char mult; /* frequency multiplication factor 0..15 */ |
unsigned char ksl; /* Key Scale Level 0..3 */ |
unsigned char outlev; /* output level 0..63 */ |
} modultr; |
unsigned char feedback;/* FeedBack Modulation Factor 0..7 */ |
unsigned char conn; /* Synthesis type: 0=FM / 1=Additive */ |
}; |
enum MDR_OPL_TIMER { |
MDR_OPL_TIMER_80US = 2, |
MDR_OPL_TIMER_320US = 3 |
}; |
/* frequency groups, to be used with mdr_opl_noteon() and mdr_opl_notebend(). |
* There are 7 frequency groups to choose from. Each group supports a different |
* span of frequencies. Higher groups have wider spans, but at the cost of larger |
* difference between adjacent notes: |
* |
* Block Note 0 Note 1023 Step gap between adjacent notes |
* FGROUP0 0.047 Hz 48.503 Hz 0.048 Hz |
* FGROUP1 0.094 Hz 97.006 Hz 0.095 Hz |
* FGROUP2 0.189 Hz 194.013 Hz 0.190 Hz |
* FGROUP3 0.379 Hz 388.026 Hz 0.379 Hz |
* FGROUP4 0.758 Hz 776.053 Hz 0.759 Hz |
* FGROUP5 1.517 Hz 1552.107 Hz 1.517 Hz |
* FGROUP6 3.034 Hz 3104.215 Hz 3.034 Hz |
* FGROUP7 6.068 Hz 6208.431 Hz 6.069 Hz |
* |
* This shows that block 7 is capable of reaching the highest note (6.2kHz) but |
* since there are 6 Hz between notes the accuracy suffers. Example: note A-4 |
* is 440Hz but in this block, the two closest frequency numbers are 72 and 73, |
* which create tones at 437Hz and 443Hz respectively, neither of which is |
* particularly accurate. Blocks 3 and below are unable to reach as high as |
* 440Hz, but block 4 can. With block 4, frequency numbers 579 and 580 produce |
* 439.4 Hz and 440.2 Hz, considerably closer to the intended frequency. |
* |
* In other words, when calculating notes, the best accuracy is achieved by |
* selecting the lowest possible block number that can reach the desired note |
* frequency. |
* |
* More details: https://moddingwiki.shikadi.net/wiki/OPL_chip#A0-A8:_Frequency_Number |
*/ |
enum mdr_opl_fgroup_t { |
MDR_OPL_FGROUP0 = 0, |
MDR_OPL_FGROUP1 = 1 << 2, |
MDR_OPL_FGROUP2 = 2 << 2, |
MDR_OPL_FGROUP3 = 3 << 2, |
MDR_OPL_FGROUP4 = 4 << 2, |
MDR_OPL_FGROUP5 = 5 << 2, |
MDR_OPL_FGROUP6 = 6 << 2, |
MDR_OPL_FGROUP7 = 7 << 2 |
}; |
/* Hardware detection and initialization. Must be called before any other |
* OPL function. Returns 0 on success, non-zero otherwise. */ |
int mdr_opl_init(void); |
/* close OPL device */ |
void mdr_opl_close(void); |
/* turns off all notes */ |
void mdr_opl_clear(void); |
/* loads an instrument described by properties in a timbre_t struct into |
* the defined voice channel. The OPL2 chip supports up to 9 voice channels, |
* from 0 to 8. The timbre struct can be freed right after this call. */ |
void mdr_opl_loadinstrument(unsigned char voice, const struct mdr_opl_timbre *timbre); |
/* generate a timbre structure based on a timbre template. this is a |
* convenience function meant to provide a human-compatible (more readable) |
* way of generating a timbre struct. */ |
int mdr_opl_timbre_gen(struct mdr_opl_timbre *timbre, const struct mdr_opl_timbretemplate *tpl); |
/* Triggers a note on selected voice channel. |
* freqid is a value between 0 and 1023. The following formula can be used to |
* determine the freq number for a given note frequency (Hz) and block: |
* |
* freqid = frequency * 2^(20 - block) / 49716 |
* |
* The note will be kept "pressed" until mdr_opl_noteoff() is called. */ |
void mdr_opl_noteon(unsigned char voice, unsigned short freqid, enum mdr_opl_fgroup_t fgroup); |
/* changes the frequency of the note currently playing on voice channel, this |
* can be used for pitch bending. */ |
void mdr_opl_notebend(unsigned char voice, unsigned short freqid, enum mdr_opl_fgroup_t fgroup); |
/* releases a note on selected voice. */ |
void mdr_opl_noteoff(unsigned char voice); |
/* adjusts volume of a voice. volume goes from 63 (mute) to 0 (loudest) */ |
void mdr_opl_voicevolume(unsigned char voice, unsigned char volume); |
/* this is a LOW-LEVEL function that writes a data byte into the reg register |
* of the OPL chip. Use this only if you know exactly what you are doing. */ |
void mdr_opl_regwr(unsigned char reg, unsigned char data); |
/***************************************************************************** |
* IMF AUDIO FILES PLAYBACK * |
* * |
* It is possible to mix IMF playback calls with manual notes, but you must * |
* take care to use only voices not used by your IMF audio. Typically games * |
* tend to use the voice #0 for sound effects and voices #1 to #8 for music. * |
* * |
* The IMF API comes in two version: the normal one, or "imfeasy". The easy * |
* version is easier to use, but requires to have the entire IMF audio file * |
* loaded in memory, while the normal (non-easy) allows for more flexibility * |
* in this regard, potentially allowing for playback of huge IMF files. * |
*****************************************************************************/ |
/*** EASY INTERFACE ***/ |
/* playback initialization, easy interface. imf points to the start of the IMF |
* file. The imf pointer must not be freed as long as playback is ongoing. |
* imflength is the size (in bytes) of the IMF data. |
* clock must be an incrementing value that wraps to 0 after 65535. The clock |
* speed will control the playback's tempo. |
* loopscount tells how many times the song will have to be looped (0 means |
* "loop forever"). |
* returns 0 on success, non-zero otherwise. */ |
int mdr_opl_imfeasy_init(void *imf, unsigned short imflength, unsigned short clock, unsigned char loopscount); |
/* Playback of an IMF file preloaded via mdr_opl_imfeasy_init(). This function |
* must be called repeatedly at a high frequency for best playback quality. |
* Returns 0 on success, 1 if playback ended, -1 on error. */ |
int mdr_opl_imfeasy_play(unsigned short clock); |
/*** ADVANCED INTERFACE ***/ |
/* playback initialization, this function must be called immediately before |
* playback. imf points to the start of the IMF file and must contain at least |
* the first 6 bytes of the audio file. |
* clock must be an incrementing value that wraps to 0 after 65535. |
* the clock speed will control the playback's tempo. |
* returns the amount of consumed bytes (0, 4 or 6) */ |
unsigned short mdr_opl_imf_init(void *imf, unsigned short clock); |
/* Playback, advanced version. Feeds the IMF playback routine with IMF data. |
* Returns the amount of bytes that have been consumed, hence the next call |
* should provide an imf pointer advanced by this many bytes (and imflen |
* decreased accordingly). Such approach might not be the most intuitive, but |
* it allows to load an imf song partially and provide only short chunks of |
* data for playback instead of having to buffer the entire song in memory. |
* For a simpler call that requires to buffer the entire IMF file in memory, |
* see mdr_opl_imf_playeasy(). |
* This function must be called repeatedly at a high frequency for best |
* playback quality. */ |
unsigned short mdr_opl_imf_play(void *imf, unsigned short imflen, unsigned short clock); |
/***************************************************************************** |
* OPL TIMER FUNCTIONS * |
*****************************************************************************/ |
/* configures and starts a timer given type so it emits a tick every count |
* periods. Two timer types are available: |
* MDR_OPL_TIMER_80US - with a period of 80us |
* MDR_OPL_TIMER_320US - with a period of 320us |
* count may range from 0 to 255, but 0 means "256 periods". |
* |
* You may use only one timer at a time. |
* |
* EXAMPLE: setting up MDR_OPL_TIMER_80US with a count of 25 would make the |
* timer tick every 2ms (25 * 80us). */ |
void mdr_opl_timer_set(enum MDR_OPL_TIMER timertype, unsigned char count); |
/* returns 1 if timer tick occured, 0 otherwise. After a tick has been |
* returned, this function will return 0 until next tick. |
* |
* it is important to note that there is no way to know whether one tick |
* passed since last time, or more, so it is up to you to make sure you call |
* this function fast enough. */ |
unsigned char mdr_opl_timer_tick(void); |
#endif |
/sved/tags/2024.1/mdr/inc/mdr/pcx.h |
---|
0,0 → 1,77 |
/* |
* 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-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_PCX_H |
#define MDR_PCX_H |
#include <stdio.h> /* FILE */ |
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]; |
}; |
/* analyzes the header of a PCX file and fills the pcx_hdr struct accordingly. |
* fd must be a valid (open) file descriptor. |
* offset is the address inside the file where the PCX data is located |
* (usually 0, unless the file is some kind of container). |
* len is the total length of the PCX data. len=0 means "same as file size" |
* returns 0 on success, non-zero otherwise. */ |
int mdr_pcx_anal(struct pcx_hdr *h, FILE *fd, unsigned long offset, unsigned long len); |
/* this function should be called to load the next row of a PCX file into a |
* buffer pointed at by bufptr. you will typically want to call this function |
* h->max_y times. ptr must be at least (h->max_x + 1) bytes large for 8bpp. |
* the pcx_hdr struct must have been produced by pcx_anal(). |
* returns 0 on success, non-zero otherwise. */ |
int mdr_pcx_loadrow(void *bufptr, const struct pcx_hdr *h, FILE *fd); |
/* load an entire PCX file into a pixel buffer. the PCX data must have been |
* previously analyzed by pcx_anal() and the fd file pointer must not have been |
* modified since then. the destination buffer must be large enough to hold all |
* pixels, ie. (h->max_x + 1) * (h->max_y + 1) for 8 bpp. |
* returns 0 on success, non-zero otherwise. */ |
int mdr_pcx_load(void *ptr, const struct pcx_hdr *h, FILE *fd); |
/* convert img to 8bpp if needed (ie unpack 2 and 4bpp data to 8bpp). |
* the conversion is performed in-place, make sure the img buffer is large |
* enough to accomodate the size of the data after conversion (ie. twice as |
* big on 4bpp source, 4x times as big on 2bpp source and 8x as big on 1bpp |
* source). |
* if rowflag is set to a non-zero value, then the routine assumes img |
* contains only a single row of pixels */ |
int mdr_pcx_to8bpp(void *img, const struct pcx_hdr *h, unsigned char rowflag); |
#endif |
/sved/tags/2024.1/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/2024.1/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/2024.1/mdr/inc/mdr/timer.h |
---|
0,0 → 1,51 |
/* |
* 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-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_TIMER_H |
#define MDR_TIMER_H |
/* Starts the timer by reprogramming the 8253 chip from its default 18.2 Hz |
* frequency to about 1.1 kHz. It is mandatory to revert the timer to its |
* original frequency via mdr_timer_stop() before your application quits. */ |
void mdr_timer_init(void); |
/* Fills res with the amount of microseconds that elapsed since either |
* mdr_timer_init() or mdr_timer_reset(), whichever was called last. |
* Note that the res counter wraps around approximately every 71 minutes if |
* mdr_timer_reset() is not called. */ |
void mdr_timer_read(unsigned long *res); |
/* Reset the timer value, this can be used by the application to make sure |
* no timer wrap occurs during critical parts of your code flow */ |
void mdr_timer_reset(void); |
/* Stops (uninstalls) the timer. This must be called before your application |
* quits, otherwise the system will likely crash. This function has a void |
* return value so that it can be registered as an atexit() procedure. */ |
void mdr_timer_stop(void); |
#endif |
/sved/tags/2024.1/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/2024.1/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/2024.1/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/2024.1/mdr/inc/mdr/vid12.h |
---|
0,0 → 1,87 |
/* |
* 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-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_VID12_H |
#define MDR_VID12_H |
/* init video mode 12h (640x480x16c) |
* remember to call vid12_close() at exit time */ |
void vid12_init(void); |
/* wait until VBLANK */ |
void vid12_waitvblank(void); |
/* wait until ANY blank: either VBLANK or HBLANK */ |
void vid12_waitblank(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); |
/* deinit video mode 12h and resets to previous mode */ |
void vid12_close(void); |
/* puts a pixel on screen */ |
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); |
/* write an entire scanline (640 pixels) to screen. the pixels data must be |
* a serie of 640 bytes having values in the range [0..15] */ |
void vid12_putscanline(unsigned short scanline, const unsigned char *pixels); |
/* set index palette color to given R,G,B value. each R,G,B component must be |
* a 6 bit value in the range [0..63] (where 63 is the maximum luminosity) */ |
void vid12_setpalette(unsigned char index, unsigned char r, unsigned char g, unsigned char b); |
/***************************** |
* VRAM TO VRAM operations * |
*****************************/ |
/* 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); |
#endif |
/sved/tags/2024.1/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/2024.1/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/2024.1/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/2024.1/mdr/mdrs2024.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/2024.1/mdr/readme.txt |
---|
0,0 → 1,78 |
Mateusz' DOS Routines |
http://mdrlib.sourceforge.io |
Mateusz' DOS Routines (MDR) is a C library that contains 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 |
OPL OPL2 (Adlib style) audio |
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 (1 kHz) 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 in header (*.H) files in the INC\MDR\ directory. |
+============================================================================+ |
| 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\dos.h> |
int main(void) { |
mdr_dos_getkey(); |
return(0); |
} |
How to compile with the Watcom C Compile and Link Utility: |
wcl -ms kbtest.c mdrs2024.lib |
+============================================================================+ |
| COMPILATION FROM SOURCES | |
+============================================================================+ |
Should you wish to compile MDR from sources 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 memory model options are: |
wmake model=s |
wmake model=c |
wmake model=m |
wmake model=l |
============================================================================== |
/sved/tags/2024.1/nls/de_utf8.txt |
---|
0,0 → 1,46 |
############################################################################# |
# SVED IN GERMAN # |
# translated from English by Bernd Boeckmann & Robert Riebisch # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=MENÜ |
0.1:UNBENANNT |
0.2:GESPEICHERT |
0.4:Ungespeicherte Änderungen gehen verloren! |
0.5:ENTER = Fortsetzen |
0.6:Speichern als: |
0.7:Öffnen: |
0.8:ESC = Abbrechen |
0.9:LEER = Speichern |
0.10:FEHLER |
0.11:DATEI NICHT GEFUNDEN |
0.12:Zu viele Dateien |
#################### |
# CONSOLE MESSAGES # |
#################### |
1.1:[Datei1.txt] ... [Datei2.txt] |
1.2:Wird geladen |
1.3:Sved, der SvarDOS-Editor |
1.4:ver |
1.10:/m Monochrommodus erzwingen |
1.11:/t Tab-Zeichen nicht expandieren |
######## |
# MENU # |
######## |
8.1:Datei öffnen |
8.2:Speichern |
8.3:Speichern als... |
8.4:Datei schließen |
8.5:EOL ändern |
8.6:Beenden |
/sved/tags/2024.1/nls/en_utf8.txt |
---|
0,0 → 1,53 |
############################################################################# |
# SVED IN ENGLISH # |
############################################################################# |
############################################################################# |
# # |
# IMPORTANT: EN strings must be as compact as possible as to not increase # |
# the size of the UPXed SVED binary. The size of translations is of lesser # |
# importace since these are not stored in the executable binary. # |
# # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=MENU |
0.1:UNTITLED |
0.2:SAVED |
0.4:Unsaved changes will be lost! |
0.5:ENTER = confirm |
0.6:Save as: |
0.7:Load: |
0.8:ESC = cancel |
0.9:SPACE = save |
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/2024.1/nls/fr_utf8.txt |
---|
0,0 → 1,46 |
############################################################################# |
# SVED IN FRENCH # |
# translated from English by Mateusz Viste # |
############################################################################# |
############### |
# 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 = valider |
0.6:Enreg. sous: |
0.7:Ouvrir: |
0.8:ÉCHAP = annuler |
0.9:ESPACE = enregistrer |
0.10:ERREUR |
0.11:FICHIER NON TROUVÉ |
0.12:Trop de fichiers |
#################### |
# CONSOLE MESSAGES # |
#################### |
1.1:[fichier1.txt] ... [fichier10.txt] |
1.2:Chargement de |
1.3:Sved, l'éditeur SvarDOS |
1.4:ver |
1.10:/m mode monochrome forcé |
1.11:/t ne déplie pas les tabulations |
######## |
# MENU # |
######## |
8.1:Ouvrir fichier |
8.2:Enregistrer |
8.3:Enreg. sous... |
8.4:Fermer fichier |
8.5:Changement EOL |
8.6:Sortir |
/sved/tags/2024.1/nls/pl_utf8.txt |
---|
0,0 → 1,46 |
############################################################################# |
# SVED IN POLISH # |
# translated from English by Mateusz Viste # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=MENU |
0.1:BEZ NAZWY |
0.2:ZAPISANO |
0.4:Niezapisane zmiany zostaną utracone! |
0.5:ENTER = potwierdź |
0.6:Zapisz jako: |
0.7:Otwórz: |
0.8:ESC = Anuluj |
0.9:SPACJA = zapisz |
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/2024.1/nls/regen.bat |
---|
0,0 → 1,14 |
@ECHO OFF |
utf8tocp 437 en_utf8.txt > en.txt |
utf8tocp 850 de_utf8.txt > de.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 de fr pl ru tr |
move /y out.lng ..\sved.lng |
move /y deflang.c .. |
del ??.txt |
/sved/tags/2024.1/nls/ru_utf8.txt |
---|
0,0 → 1,46 |
############################################################################# |
# SVED IN RUSSIAN # |
# translated from English by Mateusz Viste # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=МЕНЮ |
0.1:БЕЗ ИМЕНИ |
0.2:СОХРАНЕН |
0.4:Вы потеряете несохраненные данные! |
0.5:ENTER = подтвердить |
0.6:Сохранить как: |
0.7:Загрузка: |
0.8:ESC = отмена |
0.9:Пробел = сохранить |
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/2024.1/nls/tr_utf8.txt |
---|
0,0 → 1,46 |
############################################################################# |
# SVED IN TURKISH # |
# Translated from English by Berki Yenigün # |
############################################################################# |
############### |
# MAIN SCREEN # |
############### |
0.0:ESC=MENÜ |
0.1:BAŞLIKSIZ |
0.2:KAYDEDİLDİ |
0.4:Değişiklikler kaybolacak! |
0.5:ENTER = onay |
0.6:Farklı kaydet: |
0.7:Yükle: |
0.8:ESC = iptal |
0.9:BOŞLUK = kaydet |
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/2024.1/startup.asm |
---|
0,0 → 1,157 |
; WMINICRT - minimal runtime for (Open) Watcom C to generate DOS .COM files |
; |
; The default behaviour of the runtime is: |
; - sets up a stack of 400H bytes |
; - releases additional memory beyond stack to DOS |
; - panics on initialization, if not enough memory for stack size |
; - panics if running out of stack during execution |
; |
; WASM definitions: |
; STACKSIZE=<value> define stack size other than 400h |
; NOSTACKCHECK do not assemble __STK function |
; STACKSTAT remember the minimum SP, maintained by __STK__ |
; and exported via _stack_low_. |
; |
; To build an executable without build- and linker scripts run: |
; wasm startup.asm |
; wcc -0 -bt=dos -ms -os -zl your_c_file.c |
; wlink system dos com file startup,your_c_file |
; To change the stack size, add -DSTACKSIZE=<value> to the wasm call |
; |
; To compile without stack checking: |
; a) compile this startup file with wasm -DNOSTACKCHECK startup.asm |
; b) call the C compiler with -s flag |
; |
; To build a debug version of your program: |
; wasm -d1 startup.asm |
; wcc -bt=dos -ms -d2 -zl your_c_file.c |
; wlink system dos com debug all option map file startup,your_c_file |
; |
; TODO: |
; - display stack statistics on program termination if STACKSTAT is enabled |
; - proper Makefiles |
; - many more (optional) things while keeping it small :-) |
.8086 |
IFNDEF STACKSIZE |
STACKSIZE = 400h |
ENDIF |
DGROUP group _TEXT,_DATA,CONST,CONST2,_BSS,_STACK |
extrn "C",main : near |
public _cstart_, _small_code_ |
_TEXT segment word public 'CODE' |
org 100h |
_small_code_ label near |
_cstart_ proc |
; DOS puts the COM program in the largest memory block it can find |
; and sets SP to the end of this block. On top of that, it reserves |
; the entire memory (not only the process' block) to the program, which |
; makes it impossible to allocate memory or run child processes. |
; for this reasons it is beneficial to resize the memory block we occupy |
; into a more reasonable value |
@verify_stack_size: |
cmp sp,offset DGROUP:_stack_end_ |
ja @resize_mem |
mov dx,offset @memerr |
jmp _panic_ |
@memerr db 'MEMERR$' |
; step 2: resize our memory block to sp bytes (ie. sp/16 paragraphs) |
@resize_mem: |
mov sp,offset DGROUP:_stack_end_ |
IFDEF STACKSTAT |
mov [_stack_low_],sp |
ENDIF STACKSTAT |
mov ah,4ah |
mov bx,sp |
add bx,0fh |
shr bx,1 |
shr bx,1 |
shr bx,1 |
shr bx,1 |
int 21h |
; clear _BSS to be ANSI C conformant |
mov di,offset DGROUP:_BSS |
mov cx,offset DGROUP:_STACK |
sub cx,di |
shr cx,1 |
xor ax,ax |
cld |
rep stosw |
call main |
mov ah,4ch |
int 21h |
_cstart_ endp |
_panic_ proc |
; output error message in DX, then terminate with FF |
mov ah,9 |
int 21h |
mov ax,4cffh ; terminate if not enough stack space |
int 21h |
_panic_ endp |
IFNDEF NOSTACKCHECK |
public __STK |
__STK proc |
; ensures that we have enough stack space left. the needed bytes are |
; given in AX. panics if stack low. |
sub ax,sp ; subtract needed bytes from SP |
neg ax ; SP-AX = -(AX-SP) |
cmp ax,offset DGROUP:_STACK - 2 ; -2 is to compensate for __STK ret addr |
jae @l1 ; enough stack => return, else panic |
int 3 ; trap into debugger |
mov dx,offset @stkerr |
add sp,200h ; make sure we have enough stack to call DOS |
jmp _panic_ |
@stkerr db 'STKERR$' |
@l1: |
IFDEF STACKSTAT ; update lowest stack pointer if statistics enabled |
cmp [_stack_low_],ax |
jbe @r |
mov [_stack_low_],ax |
ENDIF STACKSTAT |
@r: |
ret |
__STK endp |
ENDIF |
_DATA segment word public 'DATA' |
_DATA ends |
CONST segment word public 'DATA' |
CONST ends |
CONST2 segment word public 'DATA' |
CONST2 ends |
_BSS segment word public 'BSS' |
IFDEF STACKSTAT |
public _stack_low_ |
_stack_low_: dw 1 dup(?) |
ENDIF STACKSTAT |
_BSS ends |
; stack definition, available memory is checked at runtime |
; defined as segment so that linker may detect .COM size overflow |
_STACK segment para public 'TINY_STACK' |
public _stack_end_ |
db STACKSIZE dup(?) |
_stack_end_: |
_STACK ends |
_TEXT ends |
end _cstart_ |
/sved/tags/2024.1/svarlang |
---|
0,0 → 1,0 |
link ../../svarlang.lib/tags/20240227 |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/sved/tags/2024.1/sved.c |
---|
0,0 → 1,1477 |
/* Sved, the SvarDOS editor |
* |
* Copyright (C) 2023-2024 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 <i86.h> /* MK_FP() */ |
#include "mdr\bios.h" |
#include "mdr\cout.h" |
#include "mdr\dos.h" |
#include "svarlang\svarlang.h" |
#define PVER "2024.1" |
#define PDATE "2023-2024" |
/***************************************************************************** |
* 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 char buff[512]; /* short lived buffer for whatever needed */ |
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 slotid; /* 0..9 */ |
char fname[128]; |
}; |
/***************************************************************************** |
* assembly pragma "functions" * |
*****************************************************************************/ |
unsigned short dos_alloc(unsigned short siz); |
#pragma aux dos_alloc = \ |
"mov ah, 0x48" \ |
"int 0x21" \ |
"jnc done" \ |
"xor ax, ax" \ |
"done:" \ |
parm [bx] \ |
value [ax]; |
unsigned short dos_free(unsigned short segn); |
#pragma aux dos_free = \ |
"mov ah, 0x49" \ |
"int 0x21" \ |
"jc done" \ |
"xor ax, ax" \ |
"done:" \ |
parm [es] \ |
value [ax]; |
/* mode 0x3C = create or truncate file ; model 0x3D = open for read |
* returns 0 on failure, file handle otherwise */ |
unsigned short dos_fopen(const char *fname, unsigned char mode); |
#pragma aux dos_fopen = \ |
"xor al, al" \ |
"xor cx, cx" \ |
"int 0x21" \ |
"jnc DONE" \ |
"xor ax, ax" \ |
"DONE:" \ |
parm [dx] [ah] \ |
modify [cx] \ |
value [ax]; |
unsigned short dos_fclose(unsigned short handle); |
#pragma aux dos_fclose = \ |
"mov ah,0x3e" \ |
"int 0x21" \ |
"jc done" \ |
"xor ax, ax" \ |
"done:" \ |
parm [bx] \ |
value [ax]; |
unsigned short dos_fread(unsigned short handle, void *buf, unsigned short count, unsigned short *bytes); |
#pragma aux dos_fread = \ |
"mov ah, 0x3f" \ |
"int 0x21" \ |
"jc done" \ |
"mov [di], ax" \ |
"xor ax, ax" \ |
"done:" \ |
parm [bx] [dx] [cx] [di] \ |
value [ax] |
unsigned short dos_resizeblock(unsigned short siz, unsigned short segn); |
#pragma aux dos_resizeblock = \ |
"mov ah, 0x4a" \ |
"int 0x21" \ |
"jc done" \ |
"xor ax, ax" \ |
"done:" \ |
parm [bx] [es] \ |
value [ax] |
unsigned short dos_fwrite(unsigned short handle, unsigned short count, unsigned short *bytes, const void far *buf); |
/* NOTE: last parameter (far pointer buf) is passed on the stack */ |
#pragma aux dos_fwrite = \ |
"push ds" /* save DS into AX */ \ |
"pop ax" \ |
"pop dx" \ |
"pop ds" \ |
"push ax" /* save DS into stack for later restoration */ \ |
"mov ah, 0x40" \ |
"int 0x21" \ |
"pop ds" \ |
"jc done" \ |
"mov [di], ax" \ |
"xor ax, ax" \ |
"done:" \ |
parm [bx] [cx] [di] \ |
modify [dx] \ |
value [ax] |
/***************************************************************************** |
* functions * |
*****************************************************************************/ |
static size_t strlen(const char *s) { |
const char *ptr = s; |
while (*ptr != 0) ptr++; |
return(ptr - s); |
} |
static void bzero(void *ptr, size_t len) { |
char *p = ptr; |
while (len > 0) { |
*p = 0; |
p++; |
len--; |
} |
} |
static void fmemmove(void far *dst, const void far *src, size_t len) { |
short delta = 1; |
/* detect possible overlap in the forward direction */ |
if (dst >= src) { |
dst = (char far *)dst + len - 1; |
src = (char far *)src + len - 1; |
delta = -1; |
} |
while (len-- > 0) { |
*(char far *)dst = *(char far *)src; |
dst = (char far *)dst + delta; |
src = (char far *)src + delta; |
} |
} |
static struct line far *line_calloc(unsigned short siz) { |
struct line far *res; |
unsigned short seg; |
seg = dos_alloc((sizeof(struct line) + siz + 15) / 16); |
if (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_free(FP_SEG(ptr)); |
} |
static int curline_resize(struct file *db, unsigned short newsiz) { |
struct line far *newptr; |
/* try resizing the block (much faster) */ |
if (dos_resizeblock((sizeof(struct line) + newsiz + 15) / 16, FP_SEG(db->cursor)) == 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 x; |
int k; |
if (maxlen == 0) return; |
maxlen--; /* make room for the nul terminator */ |
/* print query string */ |
x = mdr_cout_str(screenlastrow, 0, query, SCHEME_STBAR3, 40); |
mdr_cout_char_rep(screenlastrow, x++, ' ', SCHEME_STBAR3, screenw - x); |
for (;;) { |
mdr_cout_locate(screenlastrow, 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(screenlastrow, x + len, ' ', SCHEME_STBAR3); |
} |
break; |
default: |
if ((k <= 0xff) && (k >= ' ') && (len < maxlen)) { |
mdr_cout_char(screenlastrow, 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 *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; |
} |
/* saves db file, resets db->modflag on success and overwrites the filename |
* field if saveas is not NULL */ |
static int savefile(struct file *db, const char *saveas) { |
int fd = 0; |
const struct line far *l; |
unsigned short 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; |
fd = dos_fopen(saveas, 0x3C /* create or truncate file */); |
if (fd == 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_fwrite(fd, l->len, &bytes, l->payload); |
} else if (l->next == NULL) { |
break; |
} |
errflag |= dos_fwrite(fd, eollen, &bytes, eolbuf); |
l = l->next; |
} |
errflag |= dos_fclose(fd); |
/* did it all work? */ |
if (errflag == 0) { |
db->modflag = 0; |
if (saveas != db->fname) mdr_dos_truename(db->fname, saveas); |
} |
return(errflag); |
} |
static void ui_statusbar(const struct file *db) { |
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 (db->slotid == 9) { |
slot[1] = '1'; |
} else { |
slot[2] += db->slotid + 1; |
} |
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(unsigned short msgid1, unsigned short msgid2, unsigned short msgid3, unsigned char attr) { |
unsigned short x, y, maxmsglen, i; |
unsigned short msgcount = 1; |
const char *msg[3]; |
msg[0] = svarlang_strid(msgid1); |
if (msgid2 != 0) { |
msgcount = 2; |
msg[1] = svarlang_strid(msgid2); |
} |
if (msgid3 != 0) { |
msgcount = 3; |
msg[2] = svarlang_strid(msgid3); |
} |
/* find longest msg */ |
maxmsglen = 0; |
for (i = 0; i < msgcount; i++) { |
y = strlen(msg[i]); |
if (y > maxmsglen) maxmsglen = y; |
} |
y = (screenh - 6) >> 1; |
x = (screenw - maxmsglen - 3) >> 1; |
for (i = y+1+msgcount; i >= y; i--) mdr_cout_char_rep(i, x, ' ', attr, maxmsglen + 2); |
x++; |
for (i = 0; i < msgcount; i++) { |
mdr_cout_str(y+1+i, x, msg[i], attr, maxmsglen); |
} |
if (uidirty.from > y) uidirty.from = y; |
if (uidirty.to < y+4) uidirty.to = y+4; |
} |
/* returns 0 if operation may proceed, non-zero to cancel */ |
static unsigned char ui_confirm_if_unsaved(struct file *db) { |
int k; |
if (db->modflag == 0) return(0); |
mdr_cout_cursor_hide(); |
/* if file has been modified then ask for confirmation: |
* ENTER : agree to data loss |
* SPACE : SAVE file before quit (only if valid filename present) |
* anything else: ABORT */ |
ui_msg(4, 5, (db->fname[0])?9:8, SCHEME_MSG); |
k = mdr_dos_getkey2(); |
mdr_cout_cursor_show(); |
/* ENTER = agree to loose unsaved data */ |
if (k == '\r') return(0); |
/* SPACE = save file and continue */ |
if ((k == ' ') && (db->fname[0] != 0) && (savefile(db, NULL) == 0)) return(0); |
/* any other key = cancel operation */ |
return(1); |
} |
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_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 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 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 *buffptr; |
unsigned short len, llen; |
unsigned short 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 (take care to preserve the id of the slot, though) */ |
{ |
unsigned char slotid = db->slotid; |
bzero(db, sizeof(struct file)); |
db->slotid = slotid; |
} |
/* start by adding an empty line */ |
if (line_add(db, NULL, 0) != 0) return(2); |
if (fname == NULL) goto SKIPLOADING; |
/* make the filename canonical (DOS 3+ only, on earlier versions it just copies the filename) */ |
mdr_dos_truename(db->fname, fname); |
/* fopen file */ |
fd = dos_fopen(fname, 0x3D /* open for read */); |
if (fd == 0) err = LOADFILE_FILENOTFOUND; |
if (err != 0) goto SKIPLOADING; |
db->lfonly = 1; |
for (eolfound = 0;;) { |
unsigned short consumedbytes; |
if ((dos_fread(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') && (!glob_tablessmode)) { |
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; |
} |
/* tab: append enough spaces to land on next 8-chars boundary */ |
if ((consumedbytes < len) && (buffptr[consumedbytes] == '\t') && (glob_tablessmode == 0)) { |
consumedbytes++; |
if (line_append(db, " ", 8 - (db->cursor->len & 7)) != 0) { |
goto IOERR; |
} |
} |
/* anything left? process the buffer leftover again */ |
if (consumedbytes < len) { |
len -= consumedbytes; |
buffptr += consumedbytes; |
goto FINDLINE; |
} |
} |
dos_fclose(fd); |
SKIPLOADING: |
/* rewind cursor to top of file because it has been used by line_add() */ |
db_rewind(db); |
return(err); |
IOERR: |
dos_fclose(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_str(" " PVER "]\r\n" |
"Copyright (C) " PDATE " Mateusz Viste\n" |
"\r\n" |
"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 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 void new_slot_selected(const struct file *dbarr) { |
uidirty.from = 0; |
uidirty.to = 0xff; |
uidirty.statusbar = 1; |
/* 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); |
ui_refresh(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]; |
struct file *db = dbarr; /* visible file is the first slot by default */ |
static struct line far *clipboard; |
static unsigned char original_breakflag; |
{ /* load NLS resource */ |
unsigned short i = 0; |
const char far *selfptr; |
char lang[8]; |
selfptr = mdr_dos_selfexe(); |
if (selfptr != NULL) { |
do { |
buff[i] = selfptr[i]; |
} while (buff[i++] != 0); |
svarlang_autoload_exepath(buff, mdr_dos_getenv(lang, "LANG", sizeof(lang))); |
} |
} |
/* preload all slots with empty files */ |
{ |
unsigned short i; |
for (i = 0; i < 10; i++) { |
loadfile(&(dbarr[i]), NULL); |
dbarr[i].slotid = i; |
} |
} |
/* 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); |
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(4, 8, 0, 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(11, 0, 0, SCHEME_ERR); /* file not found */ |
} else { |
ui_msg(10, 0, 0, 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); |
} else { |
saveflag = savefile(db, NULL); |
} |
mdr_cout_cursor_hide(); |
if (saveflag == 0) { |
ui_msg(2, 0, 0, SCHEME_MSG); |
mdr_bios_tickswait(11); /* 11 ticks is about 600 ms */ |
} else { |
ui_msg(10, 0, 0, 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; |
{ |
unsigned short curfile; |
for (curfile = 0; curfile < 10; curfile++) { |
if (dbarr[curfile].modflag == 0) continue; /* skip unmodified slots */ |
db = dbarr + curfile; |
new_slot_selected(db); |
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: fill blanks to next 8-chars boundary */ |
if (glob_tablessmode == 0) { |
insert_in_line(db, " ", 8 - ((db->xoffset + db->cursorposx) & 7)); |
} else { |
insert_in_line(db, "\t", 1); |
} |
} else if ((k >= 0x13b) && (k <= 0x144)) { /* F1..F10 */ |
db = dbarr + (k - 0x13b); |
new_slot_selected(db); |
} 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(10, 0, 0, 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; |
db->modflag = 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(10, 0, 0, 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); |
db->modflag = 1; |
} |
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/2024.1/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/2024.1/sved.lnk |
---|
0,0 → 1,9 |
name sved |
system dos com |
option map |
option nodefaultlibs |
file startup |
file sved |
file deflang |
lib svarlang\svarlngs |
lib mdr\mdrs2024.lib |
/sved/tags/2024.1/sved.txt |
---|
0,0 → 1,130 |
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 6 KiB of disk footprint |
- screen estate dedicated to text (no stupid frames, menus and such) |
- loads files larger than 64 KiB (limited to available conventional memory) |
- 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 the two |
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: DE 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 ################################################################ |
2024.1 [27 Feb 2024] |
- fixed tab-less mode [/t] (got broken in 2024.0 inducing freezes) |
- fixed a register trashing during file save (potential cause of crash) |
- updated german translations, courtesy of Robert Riebisch |
- updated the SvarLANG library to ver 20240227 |
2024.0 [22 Feb 2024] |
- TAB jumps to nearest 8-chars boundary instead of always inserting 8 blanks |
2023.5 [15 Nov 2023] |
- modified files can be saved at exit time with the space key |
- fix: CTRL+X and CTRL+V were not flagging the file as "modified" |
- improved compatibility with DOS 2.x |
- removed the Watcom RTL; HUGE thanks to Bernd Boeckmann for WMINCRT |
- SVED's disk footprint decreased from 7K to 6K |
2023.4 [27 Aug 2023] |
- added german translation, credits to Bernd Boeckmann |
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-2024 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 ### |