//sved/trunk/libc.c |
---|
0,0 → 1,211 |
/* |
* replacement for a couple of libc functions |
*/ |
#include <i86.h> |
#include <stddef.h> |
#include "libc.h" |
size_t strlen(const char *s) { |
size_t res = 0; |
while (s[res] != 0) res++; |
return(res); |
} |
void bzero(void *ptr, size_t len) { |
while (len > 0) ((char *)ptr)[--len] = 0; |
} |
/* TODO this function does not handle overlapping strings well! */ |
void far *_fmemmove(void far *dst, const void far *src, size_t len) { |
while (len-- > 0) { |
((char far *)dst)[len] = ((char far *)src)[len]; |
} |
return(dst); |
} |
unsigned short mdr_dos_fopen(const char *fname, unsigned short *fhandle) { |
unsigned short res = 0; |
unsigned short handle = 0; |
unsigned short fname_seg = FP_SEG(fname); |
unsigned short fname_off = FP_OFF(fname); |
_asm { |
push cx |
push dx |
mov ax, 0x3d00 |
mov dx, fname_off |
xor cl, cl |
push ds |
mov ds, fname_seg |
int 0x21 |
pop ds |
jc err |
mov handle, ax |
jmp done |
err: |
mov res, ax |
done: |
pop dx |
pop cx |
} |
*fhandle = handle; |
return(res); |
} |
unsigned short mdr_dos_fclose(unsigned short handle) { |
unsigned short res = 0; |
_asm { |
push bx |
mov ah, 0x3e |
mov bx, handle |
int 0x21 |
jnc done |
mov res, ax |
done: |
pop bx |
} |
return(res); |
} |
unsigned short _dos_freemem(unsigned short segn) { |
unsigned short res = 0; |
_asm { |
push es |
mov ah, 0x49 |
mov es, segn |
int 0x21 |
pop es |
jnc done |
mov res, ax |
done: |
} |
return(res); |
} |
unsigned short mdr_dos_allocmem(unsigned short siz) { |
unsigned short segnum = 0; |
_asm { |
push bx |
mov ah, 0x48 |
mov bx, siz |
int 0x21 |
jc done |
mov segnum, ax |
done: |
pop bx |
} |
return(segnum); |
} |
unsigned short mdr_dos_resizeblock(unsigned short siz, unsigned short segn, unsigned short *maxsiz) { |
unsigned short resbx = 0; |
unsigned short res = 0; |
_asm { |
push bx |
push es |
mov ah, 0x4a |
mov bx, siz |
mov es, segn |
int 0x21 |
jnc done |
mov resbx, bx |
mov res, ax |
done: |
pop es |
pop bx |
} |
*maxsiz = resbx; |
return(res); |
} |
unsigned short mdr_dos_read(unsigned short handle, void far *buf, unsigned short count, unsigned short *bytes) { |
unsigned short res = 0; |
unsigned short resax = 0; |
unsigned short buf_off = FP_OFF(buf); |
unsigned short buf_seg = FP_SEG(buf); |
_asm { |
push bx, |
push cx |
push dx |
mov ah, 0x3f |
mov bx, handle |
mov cx, count |
mov dx, buf_off |
push ds |
mov ds, buf_seg |
int 0x21 |
pop ds |
jnc done |
mov res, ax |
done: |
mov resax, ax |
pop dx |
pop cx |
pop bx |
} |
*bytes = resax; |
return(res); |
} |
unsigned short mdr_dos_write(unsigned short handle, const void far *buf, unsigned short count, unsigned short *bytes) { |
unsigned short res = 0; |
unsigned short resax = 0; |
unsigned short buf_seg = FP_SEG(buf); |
unsigned short buf_off = FP_OFF(buf); |
_asm { |
push bx |
push cx |
push dx |
mov ah, 0x40 |
mov bx, handle |
mov cx, count |
mov dx, buf_off |
push ds |
mov ds, buf_seg |
int 0x21 |
pop ds |
jnc done |
mov res, ax |
done: |
mov resax, ax |
pop dx |
pop cx |
pop bx |
} |
*bytes = resax; |
return(res); |
} |
//sved/trunk/libc.h |
---|
0,0 → 1,19 |
#ifndef LIBC_H |
#define LIBC_H |
#include <stddef.h> |
size_t strlen(const char *s); |
void bzero(void *ptr, size_t len); |
void far *_fmemmove(void far *dst, const void far *src, size_t len); |
unsigned short mdr_dos_fopen(const char *fname, unsigned short *fhandle); |
unsigned short mdr_dos_fclose(unsigned short handle); |
unsigned short _dos_freemem(unsigned short segn); |
unsigned short mdr_dos_allocmem(unsigned short siz); |
unsigned short mdr_dos_resizeblock(unsigned short siz, unsigned short segn, unsigned short *maxsiz); |
unsigned short mdr_dos_read(unsigned short handle, void far *buf, unsigned short count, unsigned short *bytes); |
unsigned short mdr_dos_write(unsigned short handle, const void far *buf, unsigned short count, unsigned short *bytes); |
#endif |
//sved/trunk/makefile |
---|
7,17 → 7,16 |
# wmake release builds distribuable packages (svp, zip, sources...) |
CC = wcc |
CFLAGS = -0 -ms -os -wx -we -d0 -bt=dos -I=mdr\inc |
CFLAGS = -0 -ms -zl -os -wx -we -d0 -bt=dos -I=mdr\inc |
CFLAGS += -s |
LDFLAGS = -lr -mt -fm=sved.map -fe=sved.com |
LDLIBS = svarlang\svarlngs.lib mdr\mdrs2024.lib |
PVER = 2023.5 |
all: sved.com |
sved.com: sved.obj deflang.obj |
wcl $(LDLIBS) sved.obj deflang.obj $(LDFLAGS) |
sved.com: sved.obj deflang.obj libc.obj |
wasm startup.asm |
wlink @sved.lnk |
upx -9 --8086 sved.com |
.c.obj: .autodepend |
//sved/trunk/startup.asm |
---|
0,0 → 1,76 |
.8086 |
STACK_SIZE = 2048 |
dgroup group _TEXT,_DATA,CONST,CONST2,_STACK,_BSS |
extrn "C",main : near |
; public _cstart_, _small_code_, __STK |
public _cstart_, _small_code_ |
_TEXT segment word public 'CODE' |
org 100h |
_small_code_ label near |
_cstart_: |
; 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 |
; step 1: if SP is higher than my top_of_stack, then set SP explicitely |
cmp sp, top_of_stack |
jle resizemem |
mov sp, top_of_stack |
; step 2: resize our memory block to sp bytes (ie. sp/16 paragraphs) |
resizemem: |
mov ah, 4ah |
mov bx, sp |
shr bx, 1 |
shr bx, 1 |
shr bx, 1 |
shr bx, 1 |
inc bx |
int 21h |
call main |
mov ah, 4ch |
int 21h |
; Stack overflow checking routine is absent. Remember to compile your |
; programs with the -s option to avoid referencing __STK |
;__STK: |
; ret |
_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' |
_BSS ends |
_STACK segment para public 'BSS' |
db (STACK_SIZE) dup(0) ; set this explicitely to zero, otherwise |
; static variables are not properly |
; initialized. this makes the COM file |
; much bigger, but it is irrelevant if it |
; is UPXed afterwards anyway. If you care, |
; then you may zero out this area in |
; code instead (before calling main) |
top_of_stack: |
_STACK ends |
_TEXT ends |
end _cstart_ |
//sved/trunk/sved.c |
---|
23,11 → 23,10 |
* IN THE SOFTWARE. |
*/ |
#include <dos.h> /* _dos_open(), _dos_read(), _dos_close(), ... */ |
#include <fcntl.h> /* O_RDONLY, O_WRONLY */ |
#include <string.h> |
#include <strings.h> |
#include <i86.h> /* MK_FP() */ |
#include "libc.h" |
#include "mdr\bios.h" |
#include "mdr\cout.h" |
#include "mdr\dos.h" |
96,10 → 95,10 |
static struct line far *line_calloc(unsigned short siz) { |
struct line far *res; |
unsigned int seg; |
unsigned short seg; |
if (_dos_allocmem((sizeof(struct line) + siz + 15) / 16, &seg) != 0) return(NULL); |
seg = mdr_dos_allocmem((sizeof(struct line) + siz + 15) / 16); |
if (seg == 0) return(NULL); |
res = MK_FP(seg, 0); |
res->len = 0; |
res->next = NULL; |
115,11 → 114,11 |
static int curline_resize(struct file *db, unsigned short newsiz) { |
unsigned int maxavail; |
unsigned short maxavail; |
struct line far *newptr; |
/* try resizing the block (much faster) */ |
if (_dos_setblock((sizeof(struct line) + newsiz + 15) / 16, FP_SEG(db->cursor), &maxavail) == 0) return(0); |
if (mdr_dos_resizeblock((sizeof(struct line) + newsiz + 15) / 16, FP_SEG(db->cursor), &maxavail) == 0) return(0); |
/* create a new block and copy data over */ |
newptr = line_calloc(newsiz); |
228,7 → 227,7 |
static int savefile(struct file *db, const char *saveas) { |
int fd = 0; |
const struct line far *l; |
unsigned int bytes; |
unsigned short bytes; |
unsigned char eollen = 2; |
const unsigned char *eolbuf = "\r\n"; |
int errflag = 0; |
269,15 → 268,15 |
while (l) { |
/* do not write the last empty line, it is only useful for edition */ |
if (l->len != 0) { |
errflag |= _dos_write(fd, l->payload, l->len, &bytes); |
errflag |= mdr_dos_write(fd, l->payload, l->len, &bytes); |
} else if (l->next == NULL) { |
break; |
} |
errflag |= _dos_write(fd, eolbuf, eollen, &bytes); |
errflag |= mdr_dos_write(fd, eolbuf, eollen, &bytes); |
l = l->next; |
} |
errflag |= _dos_close(fd); |
errflag |= mdr_dos_fclose(fd); |
/* did it all work? */ |
if (errflag == 0) { |
639,8 → 638,8 |
/* 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 int len, llen; |
int fd; |
unsigned short len, llen; |
unsigned short fd; |
unsigned char eolfound; |
unsigned char err = 0; |
668,7 → 667,7 |
/* make the filename canonical (DOS 3+ only, on earlier versions it just copies the filename) */ |
mdr_dos_truename(db->fname, fname); |
err = _dos_open(fname, O_RDONLY, &fd); |
err = mdr_dos_fopen(fname, &fd); |
if (err != 0) goto SKIPLOADING; |
db->lfonly = 1; |
676,7 → 675,7 |
for (eolfound = 0;;) { |
unsigned short consumedbytes; |
if ((_dos_read(fd, buff, sizeof(buff), &len) != 0) || (len == 0)) break; |
if ((mdr_dos_read(fd, buff, sizeof(buff), &len) != 0) || (len == 0)) break; |
buffptr = buff; |
FINDLINE: |
740,7 → 739,7 |
} |
_dos_close(fd); |
mdr_dos_fclose(fd); |
SKIPLOADING: |
750,7 → 749,7 |
return(err); |
IOERR: |
_dos_close(fd); |
mdr_dos_fclose(fd); |
return(1); |
} |
971,6 → 970,14 |
static struct line far *clipboard; |
static unsigned char original_breakflag; |
mdr_coutraw_puts("glob_monomode:"); |
mdr_coutraw_char('0' + glob_monomode); |
mdr_coutraw_crlf(); |
mdr_coutraw_puts("original_breakflag:"); |
mdr_coutraw_char('0' + original_breakflag); |
mdr_coutraw_crlf(); |
{ /* load NLS resource */ |
unsigned short i = 0; |
const char far *selfptr; |
1008,6 → 1015,10 |
SCHEME_SCROLL = 0x70; |
SCHEME_MSG = 0x6f; |
SCHEME_ERR = 0x4f; |
} else { |
// FIXME |
mdr_coutraw_char('0' + glob_monomode); |
_asm int 0x20 |
} |
screenlastrow = screenh - 1; |
screenlastcol = screenw - 1; |
//sved/trunk/sved.lnk |
---|
0,0 → 1,10 |
name sved |
system dos com |
option map |
option nodefaultlibs |
file startup |
file sved |
file deflang |
file libc |
lib svarlang\svarlngs |
lib mdr\mdrs2024.lib |