Added cpm platform.
This commit is contained in:
55
plat/cpm/libsys/_bdos.s
Normal file
55
plat/cpm/libsys/_bdos.s
Normal file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
! Declare segments (the order is important).
|
||||
|
||||
.sect .text
|
||||
.sect .rom
|
||||
.sect .data
|
||||
.sect .bss
|
||||
|
||||
.sect .text
|
||||
|
||||
! Calls a BDOS routine.
|
||||
|
||||
.define _cpm_bdos
|
||||
_cpm_bdos:
|
||||
push b
|
||||
|
||||
lda _cpm_a_register
|
||||
|
||||
lhld _cpm_bc_register
|
||||
mov b, h
|
||||
mov c, l
|
||||
|
||||
lhld _cpm_de_register
|
||||
mov d, h
|
||||
mov e, l
|
||||
|
||||
lhld _cpm_hl_register
|
||||
|
||||
call 5
|
||||
|
||||
shld _cpm_hl_register
|
||||
|
||||
mov h, d
|
||||
mov l, e
|
||||
shld _cpm_de_register
|
||||
|
||||
mov h, b
|
||||
mov l, c
|
||||
shld _cpm_bc_register
|
||||
|
||||
sta _cpm_a_register
|
||||
|
||||
pop b
|
||||
ret
|
||||
|
||||
.sect .bss
|
||||
.define _cpm_a_register, _cpm_bc_register, _cpm_de_register, _cpm_hl_register
|
||||
.comm _cpm_a_register, 1
|
||||
.comm _cpm_bc_register, 2
|
||||
.comm _cpm_de_register, 2
|
||||
.comm _cpm_hl_register, 2
|
||||
19
plat/cpm/libsys/_hol0.s
Normal file
19
plat/cpm/libsys/_hol0.s
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
! Declare segments (the order is important).
|
||||
|
||||
.sect .text
|
||||
.sect .rom
|
||||
.sect .data
|
||||
.sect .bss
|
||||
|
||||
.sect .bss
|
||||
|
||||
! This data block is used to store information about the current line number
|
||||
! and file.
|
||||
|
||||
.define hol0
|
||||
.comm hol0, 8
|
||||
50
plat/cpm/libsys/_inn2.s
Normal file
50
plat/cpm/libsys/_inn2.s
Normal file
@@ -0,0 +1,50 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
! Declare segments (the order is important).
|
||||
|
||||
.sect .text
|
||||
.sect .rom
|
||||
.sect .data
|
||||
.sect .bss
|
||||
|
||||
! Bit test on 16 bits set
|
||||
! Expects on stack: bit number
|
||||
! set to be tested
|
||||
! Yields in de-registers: 0 if bit is reset or bit number out of range
|
||||
! 1 if bit is set
|
||||
|
||||
.sect .text
|
||||
.define .inn2
|
||||
.inn2: pop h
|
||||
shld .retadr
|
||||
|
||||
pop d !bit number
|
||||
pop h !set to be tested
|
||||
mov a,e
|
||||
cpi 16
|
||||
jnc 3f
|
||||
cpi 8
|
||||
jnc 1f
|
||||
mov e,a
|
||||
mov a,l !l-reg contains the wanted bit
|
||||
jmp 2f
|
||||
|
||||
1: sbi 8
|
||||
mov e,a
|
||||
mov a,h !h-reg contains the wanted bit
|
||||
|
||||
2: dcr e
|
||||
jm 4f
|
||||
rar
|
||||
jmp 2b
|
||||
|
||||
3: xra a !return 0 if bit number out of range
|
||||
4: ani 1
|
||||
mov e,a
|
||||
mvi d,0
|
||||
|
||||
lhld .retadr
|
||||
pchl
|
||||
220
plat/cpm/libsys/_trap.s
Normal file
220
plat/cpm/libsys/_trap.s
Normal file
@@ -0,0 +1,220 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
! Declare segments (the order is important).
|
||||
|
||||
.sect .text
|
||||
.sect .rom
|
||||
.sect .data
|
||||
.sect .bss
|
||||
|
||||
.define .trp
|
||||
.define earray, erange, eset, eiovfl, efovfl, efunfl, eidivz, eidivz
|
||||
.define efdivz, eiund, efund, econv, estack, eheap, eillins, eoddz
|
||||
.define ecase, ememflt, ebadptr, ebadpc, ebadlae, ebadmon, ebadlin, ebadgto
|
||||
.define eunimpl
|
||||
|
||||
.sect .text
|
||||
|
||||
! Trap routine
|
||||
! Expects trap number on stack.
|
||||
! Just returns if trap has to be ignored.
|
||||
! Otherwise it calls a user-defined trap handler if provided.
|
||||
! When no user-defined trap handler is provided or when the user-defined
|
||||
! trap handler causes a new trap, a message is printed
|
||||
! and control is returned to the monitor.
|
||||
|
||||
EARRAY = 0
|
||||
ERANGE = 1
|
||||
ESET = 2
|
||||
EIOVFL = 3
|
||||
EFOVFL = 4
|
||||
EFUNFL = 5
|
||||
EIDIVZ = 6
|
||||
EFDIVZ = 7
|
||||
EIUND = 8
|
||||
EFUND = 9
|
||||
ECONV = 10
|
||||
ESTACK = 16
|
||||
EHEAP = 17
|
||||
EILLINS = 18
|
||||
EODDZ = 19
|
||||
ECASE = 20
|
||||
EMEMFLT = 21
|
||||
EBADPTR = 22
|
||||
EBADPC = 23
|
||||
EBADLAE = 24
|
||||
EBADMON = 25
|
||||
EBADLIN = 26
|
||||
EBADGTO = 27
|
||||
EUNIMPL = 63 ! unimplemented em-instruction called
|
||||
|
||||
earray: lxi h,EARRAY
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
erange: lxi h,ERANGE
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
eset: lxi h,ESET
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
eiovfl: lxi h,EIOVFL
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
efovfl: lxi h,EFOVFL
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
efunfl: lxi h,EFUNFL
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
eidivz: lxi h,EIDIVZ
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
efdivz: lxi h,EFDIVZ
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
eiund: lxi h,EIUND
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
efund: lxi h,EFUND
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
econv: lxi h,ECONV
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
estack: lxi h,ESTACK
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
eheap: lxi h,EHEAP
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
eillins:lxi h,EILLINS
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
eoddz: lxi h,EODDZ
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
ecase: lxi h,ECASE
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
ememflt:lxi h,EMEMFLT
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
ebadptr:lxi h,EBADPTR
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
ebadpc: lxi h,EBADPC
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
ebadlae:lxi h,EBADLAE
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
ebadmon:lxi h,EBADMON
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
ebadlin:lxi h,EBADLIN
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
ebadgto:lxi h,EBADGTO
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
eunimpl:lxi h,EUNIMPL
|
||||
push h
|
||||
call .trp
|
||||
ret
|
||||
|
||||
.trp:
|
||||
pop h
|
||||
xthl
|
||||
push h ! trap number and return address exchanged
|
||||
mov a,l
|
||||
cpi 16
|
||||
jnc 3f ! jump if trap cannot be ignored
|
||||
|
||||
! check if trap has to be ignored
|
||||
xchg ! de = trap number
|
||||
lhld .ignmask
|
||||
push h ! hl = set to be tested
|
||||
push d
|
||||
call .inn2 ! de = 1 if bit is set, 0 otherwise
|
||||
mov a,e
|
||||
rar
|
||||
jnc 3f ! jump if trap should not be ignored
|
||||
pop h ! remove trap number
|
||||
ret ! OGEN DICHT EN ... SPRING!!!
|
||||
|
||||
3:
|
||||
lhld .trapproc ! user defined trap handler?
|
||||
mov a,l
|
||||
ora h
|
||||
jz 1f ! jump if there was not
|
||||
xra a
|
||||
sta .trapproc ! .trapproc := 0
|
||||
sta .trapproc+1
|
||||
lxi d,2f
|
||||
push d
|
||||
pchl ! call user defined trap handler
|
||||
2:
|
||||
pop d
|
||||
ret
|
||||
1:
|
||||
lxi h, 1
|
||||
push h
|
||||
lxi h, text
|
||||
push h
|
||||
lxi h, 6
|
||||
push h
|
||||
call _write
|
||||
jmp EXIT
|
||||
|
||||
.sect .rom
|
||||
text: .ascii "TRAP!\n"
|
||||
|
||||
43
plat/cpm/libsys/brk.c
Normal file
43
plat/cpm/libsys/brk.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define OUT_OF_MEMORY (void*)(-1) /* sbrk returns this on failure */
|
||||
#define STACK_BUFFER 128 /* number of bytes to leave for stack */
|
||||
|
||||
extern char _end[1];
|
||||
static char* current = _end;
|
||||
|
||||
int brk(void* newend)
|
||||
{
|
||||
/* We determine the amount of free memory by looking at the address of the
|
||||
* BDOS vector at 0x0006. */
|
||||
char* memtop = (char*) ((*(unsigned char*)0x0007)<<8);
|
||||
char* p = newend;
|
||||
|
||||
if ((p >= memtop) ||
|
||||
(p < _end))
|
||||
return -1;
|
||||
|
||||
current = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* sbrk(intptr_t increment)
|
||||
{
|
||||
char* old;
|
||||
|
||||
if (increment == 0)
|
||||
return current;
|
||||
|
||||
old = current;
|
||||
if (brk(old + increment) < 0)
|
||||
return OUT_OF_MEMORY;
|
||||
|
||||
return old;
|
||||
}
|
||||
14
plat/cpm/libsys/close.c
Normal file
14
plat/cpm/libsys/close.c
Normal file
@@ -0,0 +1,14 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
13
plat/cpm/libsys/creat.c
Normal file
13
plat/cpm/libsys/creat.c
Normal file
@@ -0,0 +1,13 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int creat(const char* path, int mode)
|
||||
{
|
||||
return open(path, O_CREAT|O_WRONLY|O_TRUNC, mode);
|
||||
}
|
||||
28
plat/cpm/libsys/errno.s
Normal file
28
plat/cpm/libsys/errno.s
Normal file
@@ -0,0 +1,28 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
! Declare segments (the order is important).
|
||||
|
||||
.sect .text
|
||||
.sect .rom
|
||||
.sect .data
|
||||
.sect .bss
|
||||
|
||||
#define D(e) .define e; e
|
||||
|
||||
.sect .data
|
||||
|
||||
! Define various ACK error numbers. Note that these are *not* ANSI C
|
||||
! errnos, and are used for different purposes.
|
||||
|
||||
D(ERANGE) = 1
|
||||
D(ESET) = 2
|
||||
D(EIDIVZ) = 6
|
||||
D(EHEAP) = 17
|
||||
D(EILLINS) = 18
|
||||
D(EODDZ) = 19
|
||||
D(ECASE) = 20
|
||||
D(EBADMON) = 25
|
||||
|
||||
13
plat/cpm/libsys/getpid.c
Normal file
13
plat/cpm/libsys/getpid.c
Normal file
@@ -0,0 +1,13 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t getpid(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
13
plat/cpm/libsys/isatty.c
Normal file
13
plat/cpm/libsys/isatty.c
Normal file
@@ -0,0 +1,13 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int isatty(int fd)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
14
plat/cpm/libsys/kill.c
Normal file
14
plat/cpm/libsys/kill.c
Normal file
@@ -0,0 +1,14 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int kill(pid_t pid, int sig)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
14
plat/cpm/libsys/lseek.c
Normal file
14
plat/cpm/libsys/lseek.c
Normal file
@@ -0,0 +1,14 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
off_t lseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
14
plat/cpm/libsys/open.c
Normal file
14
plat/cpm/libsys/open.c
Normal file
@@ -0,0 +1,14 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int open(const char* path, int access, ...)
|
||||
{
|
||||
errno = EACCES;
|
||||
return -1;
|
||||
}
|
||||
29
plat/cpm/libsys/pmfile
Normal file
29
plat/cpm/libsys/pmfile
Normal file
@@ -0,0 +1,29 @@
|
||||
-- $Source$
|
||||
-- $State$
|
||||
-- $Revision$
|
||||
|
||||
local d = ROOTDIR.."plat/cpm/libsys/"
|
||||
|
||||
libsys_cpm = acklibrary {
|
||||
ACKINCLUDES = {"%BINDIR%include"},
|
||||
|
||||
ackfile (d.."errno.s"),
|
||||
ackfile (d.."_hol0.s"),
|
||||
ackfile (d.."_bdos.s"),
|
||||
ackfile (d.."_trap.s"),
|
||||
ackfile (d.."_inn2.s"),
|
||||
ackfile (d.."open.c"),
|
||||
ackfile (d.."creat.c"),
|
||||
ackfile (d.."close.c"),
|
||||
ackfile (d.."read.c"),
|
||||
ackfile (d.."write.c"),
|
||||
ackfile (d.."brk.c"),
|
||||
ackfile (d.."getpid.c"),
|
||||
ackfile (d.."kill.c"),
|
||||
ackfile (d.."isatty.c"),
|
||||
ackfile (d.."lseek.c"),
|
||||
ackfile (d.."time.c"),
|
||||
ackfile (d.."signal.c"),
|
||||
|
||||
install = pm.install("%BINDIR%lib/%PLATFORM%/libsys.a"),
|
||||
}
|
||||
38
plat/cpm/libsys/read.c
Normal file
38
plat/cpm/libsys/read.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <cpm.h>
|
||||
|
||||
int read(int fd, void* buffer, size_t count)
|
||||
{
|
||||
char i;
|
||||
|
||||
/* We're only allowed to read from fd 0, 1 or 2. */
|
||||
|
||||
if ((fd < 0) || (fd > 2))
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Empty buffer? */
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
/* Read one byte. */
|
||||
|
||||
cpm_bc_register = CPM_BDOS_CONSOLE_INPUT;
|
||||
cpm_bdos();
|
||||
|
||||
if (cpm_a_register == '\r')
|
||||
cpm_a_register = '\n';
|
||||
*(char*)buffer = cpm_a_register;
|
||||
|
||||
return 1;
|
||||
}
|
||||
14
plat/cpm/libsys/signal.c
Normal file
14
plat/cpm/libsys/signal.c
Normal file
@@ -0,0 +1,14 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
sighandler_t signal(int signum, sighandler_t handler)
|
||||
{
|
||||
return SIG_DFL;
|
||||
}
|
||||
16
plat/cpm/libsys/time.c
Normal file
16
plat/cpm/libsys/time.c
Normal file
@@ -0,0 +1,16 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
time_t time(time_t* t)
|
||||
{
|
||||
if (t)
|
||||
*t = 0;
|
||||
return 0;
|
||||
}
|
||||
51
plat/cpm/libsys/write.c
Normal file
51
plat/cpm/libsys/write.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <cpm.h>
|
||||
|
||||
void _sys_write_tty(char c)
|
||||
{
|
||||
cpm_bc_register = CPM_BDOS_CONSOLE_OUTPUT;
|
||||
cpm_de_register = c;
|
||||
cpm_bdos();
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
cpm_bc_register = CPM_BDOS_CONSOLE_OUTPUT;
|
||||
cpm_de_register = '\r';
|
||||
cpm_bdos();
|
||||
}
|
||||
}
|
||||
|
||||
int write(int fd, void* buffer, size_t count)
|
||||
{
|
||||
int i;
|
||||
char* p = buffer;
|
||||
|
||||
/* We're only allowed to write to fd 0, 1 or 2. */
|
||||
|
||||
if ((fd < 0) || (fd > 2))
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write all data. */
|
||||
|
||||
i = 0;
|
||||
while (i < count)
|
||||
{
|
||||
_sys_write_tty(*p++);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* No failures. */
|
||||
|
||||
return count;
|
||||
}
|
||||
Reference in New Issue
Block a user