Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 1555 → Rev 1556

/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