*** empty log message ***
This commit is contained in:
parent
6bbdb92784
commit
6c247029bd
18 changed files with 2846 additions and 0 deletions
28
mach/z80/libmon/Makefile
Normal file
28
mach/z80/libmon/Makefile
Normal file
|
@ -0,0 +1,28 @@
|
|||
TAIL=tail.hermac
|
||||
# Other possibilities are: tail.nascom and tail.cpm
|
||||
|
||||
all: tail.cpm tail.nascom tail.hermac
|
||||
|
||||
install: $(TAIL)
|
||||
../../install head_em.s head_em
|
||||
../../install $(TAIL) tail_sys
|
||||
|
||||
cmp: $(TAIL)
|
||||
-../../compare head_em.s head_em
|
||||
-../../compare $(TAIL) tail_sys
|
||||
|
||||
tail.cpm: mon.cpm.s
|
||||
@echo Warning: untested, this is an example
|
||||
arch cr tail.cpm mon.cpm.s
|
||||
|
||||
tail.nascom: mon.s putchr.nas.s
|
||||
arch cr tail.nascom mon.s putchr.nas.s
|
||||
|
||||
tail.hermac: mon.s char.her.s
|
||||
arch cr tail.hermac mon.s char.her.s
|
||||
|
||||
opr:
|
||||
make pr | opr
|
||||
pr:
|
||||
@pr `pwd`/Makefile `pwd`/head_em.s
|
||||
@pr `pwd`/subr.s `pwd`/mon.s `pwd`/mon.cpm.s `pwd`/putchr.s `pwd`/putchr.nas.s `pwd`/char.her.s
|
12
mach/z80/libmon/README
Normal file
12
mach/z80/libmon/README
Normal file
|
@ -0,0 +1,12 @@
|
|||
This directory contains files for three different environments:
|
||||
- The Hermac computer.
|
||||
- The Nascom computer.
|
||||
- A CPM system.
|
||||
|
||||
The default system used is the Hermac on which this software was
|
||||
tested. The Nascom environment has been known to work too.
|
||||
The CPM files are included as an example only. These have never
|
||||
been tested.
|
||||
|
||||
The definition of TAIL in the Makefile decides which environment
|
||||
you use.
|
31
mach/z80/libmon/char.her.s
Normal file
31
mach/z80/libmon/char.her.s
Normal file
|
@ -0,0 +1,31 @@
|
|||
.define getchar, putchar
|
||||
|
||||
! These getchar and putchar routines can be used for HERMAC computer
|
||||
|
||||
! Read a character from HERMAC-monitor
|
||||
! Character is returned in a-reg
|
||||
|
||||
getchar:
|
||||
in a,0xF1
|
||||
and 1
|
||||
jp z,getchar
|
||||
in a,0xF0
|
||||
cp 0x0D
|
||||
jp nz,1f
|
||||
ld a,0x0A
|
||||
1: ret
|
||||
|
||||
! Write character on HERMAC monitor
|
||||
! Assumes character in a-reg
|
||||
|
||||
putchar:
|
||||
cp 0x0A
|
||||
jp nz,1f
|
||||
ld a,0x1F
|
||||
1: push af
|
||||
2: in a,0xF1
|
||||
and 4
|
||||
jp z,2b
|
||||
pop af
|
||||
out 0xF0,a
|
||||
ret
|
80
mach/z80/libmon/head_em.s
Normal file
80
mach/z80/libmon/head_em.s
Normal file
|
@ -0,0 +1,80 @@
|
|||
.define EARRAY,ERANGE,EILLINS,EILLSIZE,ECASE,EMON,EHEAP
|
||||
.define hol0,trapproc,trpim,argv,hp,.reghp,envp,begbss,ignmask
|
||||
.define savebc,savede,savehl,saveix,saveaf,saveiy,ebadmon
|
||||
EARRAY = 0
|
||||
ERANGE = 1
|
||||
EHEAP = 17
|
||||
EILLINS=18
|
||||
EILLSIZE=19
|
||||
ECASE=20
|
||||
EMON=25
|
||||
ebadmon=25
|
||||
|
||||
|
||||
.base 0x1000
|
||||
.text
|
||||
|
||||
! clear .bss
|
||||
ld sp,0x7ffe !address of fbase
|
||||
ld de,endbss
|
||||
ld h,d
|
||||
ld l,e
|
||||
ld bc,begbss
|
||||
sbc hl,bc
|
||||
ld a,h
|
||||
or l
|
||||
jr z,1f
|
||||
2:
|
||||
xor a
|
||||
ld (de),a
|
||||
dec de
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,2b
|
||||
1: ! hl == 0
|
||||
|
||||
ld bc,envp
|
||||
push bc
|
||||
ld bc,argv
|
||||
push bc
|
||||
ld bc,1
|
||||
push bc
|
||||
call _m_a_i_n
|
||||
|
||||
jp 0x20
|
||||
|
||||
.bss
|
||||
begbss:
|
||||
.data
|
||||
hol0:
|
||||
.word 0,0
|
||||
.word 0,0
|
||||
saveaf:
|
||||
.word 0
|
||||
savebc:
|
||||
.word 0
|
||||
savede:
|
||||
.word 0
|
||||
savehl:
|
||||
.word 0
|
||||
saveix:
|
||||
.word 0
|
||||
saveiy:
|
||||
.word 0
|
||||
ignmask:
|
||||
.word 0
|
||||
hp:
|
||||
.word 0
|
||||
trapproc:
|
||||
.word 0
|
||||
trpim:
|
||||
.word 0
|
||||
argv:
|
||||
.word 3f
|
||||
envp:
|
||||
.word 0
|
||||
3:
|
||||
.asciz 'PROGRAM'
|
||||
.reghp:
|
||||
.word endbss
|
924
mach/z80/libmon/mon.cpm.s
Normal file
924
mach/z80/libmon/mon.cpm.s
Normal file
|
@ -0,0 +1,924 @@
|
|||
.define .mon
|
||||
.define uxfinish
|
||||
|
||||
! monitor instruction
|
||||
! a small collection of UNIX system calls implemented under CP/M
|
||||
|
||||
! ux_indir=e.mon
|
||||
! ux_fork=e.mon
|
||||
! ux_wait=e.mon
|
||||
! ux_link=e.mon
|
||||
! ux_exec=e.mon
|
||||
! ux_chdir=e.mon
|
||||
! ux_mknod=e.mon
|
||||
! ux_chmod=e.mon
|
||||
! ux_chown=e.mon
|
||||
! ux_break=e.mon
|
||||
! ux_stat=e.mon
|
||||
! ux_seek=e.mon
|
||||
! ux_mount=e.mon
|
||||
! ux_umount=e.mon
|
||||
! ux_setuid=e.mon
|
||||
! ux_getuid=e.mon
|
||||
! ux_stime=e.mon
|
||||
! ux_ptrace=e.mon
|
||||
! ux_alarm=e.mon
|
||||
! ux_fstat=e.mon
|
||||
! ux_pause=e.mon
|
||||
! ux_utime=e.mon
|
||||
! ux_stty=e.mon
|
||||
! ux_gtty=e.mon
|
||||
! ux_access=e.mon
|
||||
! ux_nice=e.mon
|
||||
! ux_sync=e.mon
|
||||
! ux_kill=e.mon
|
||||
! ux_dup=e.mon
|
||||
! ux_pipe=e.mon
|
||||
! ux_times=e.mon
|
||||
! ux_prof=e.mon
|
||||
! ux_unused=e.mon
|
||||
! ux_setgid=e.mon
|
||||
! ux_getgid=e.mon
|
||||
! ux_sig=e.mon
|
||||
! ux_umask=e.mon
|
||||
! ux_chroot=e.mon
|
||||
|
||||
EPERM = 1
|
||||
ENOENT = 2
|
||||
ESRCH = 3
|
||||
EINTR = 4
|
||||
EIO = 5
|
||||
ENXIO = 6
|
||||
E2BIG = 7
|
||||
ENOEXEC = 8
|
||||
EBADF = 9
|
||||
ECHILD = 10
|
||||
EAGAIN = 11
|
||||
ENOMEM = 12
|
||||
EACCES = 13
|
||||
EFAULT = 14
|
||||
ENOTBLK = 15
|
||||
EBUSY = 16
|
||||
EEXIST = 17
|
||||
EXDEV = 18
|
||||
ENODEV = 19
|
||||
ENOTDIR = 20
|
||||
EISDIR = 21
|
||||
EINVAL = 22
|
||||
ENFILE = 23
|
||||
EMFILE = 24
|
||||
ENOTTY = 25
|
||||
ETXTBSY = 26
|
||||
EFBIG = 27
|
||||
ENOSPC = 28
|
||||
ESPIPE = 29
|
||||
EROFS = 30
|
||||
EMLINK = 31
|
||||
EPIPE = 32
|
||||
EDOM = 33
|
||||
! Structure of filearea maintained by this implementation
|
||||
! First iobuffer of 128 bytes
|
||||
! Then the fcb area of 36 bytes
|
||||
! The number of bytes left in the buffer, 1 byte
|
||||
! The iopointer into the buffer, 2 bytes
|
||||
! The openflag 0 unused, 1 reading, 2 writing, 1 byte
|
||||
! The filedescriptor starting at 3, 1 byte
|
||||
! The number of CTRL-Zs that have been absorbed, 1 byte
|
||||
! The byte read after a sequence of CTRL-Zs, 1 byte
|
||||
|
||||
maxfiles=8
|
||||
filesize=128+36+1+2+1+1+1+1
|
||||
|
||||
filefcb=0 ! pointers point to fcb
|
||||
position=33
|
||||
nleft=36
|
||||
iopointer=37
|
||||
openflag=39
|
||||
fildes=40
|
||||
zcount=41
|
||||
zsave=42
|
||||
|
||||
.errnz filefcb
|
||||
|
||||
0: .space maxfiles*filesize
|
||||
filearea = 0b+128
|
||||
sibuf:
|
||||
.word 0
|
||||
.space 82
|
||||
siptr: .space 2
|
||||
saveargs:
|
||||
.space 128
|
||||
argc: .space 2
|
||||
ttymode:.byte 9,9,8,21;.short 06310+RAW*040 ! raw = 040
|
||||
|
||||
return:
|
||||
.word 0,0
|
||||
uxinit:
|
||||
xor a
|
||||
ld c,maxfiles
|
||||
ld hl,0b
|
||||
1: ld b,filesize
|
||||
2: ld (hl),a
|
||||
inc hl
|
||||
djnz 2b
|
||||
dec c
|
||||
jr nz,1b
|
||||
ret
|
||||
|
||||
uxfinish:
|
||||
ld a,maxfiles-1
|
||||
1: push af
|
||||
call closefil
|
||||
pop af
|
||||
dec a
|
||||
cp 0377
|
||||
jr nz,1b
|
||||
ret
|
||||
|
||||
.mon:
|
||||
pop ix
|
||||
ld (return),ix ! return adres
|
||||
pop de ! system call number
|
||||
xor a
|
||||
or d
|
||||
jr nz,unimpld ! too big
|
||||
ld a,e
|
||||
and 0300 ! only 64 system calls
|
||||
jr nz,unimpld
|
||||
sla e
|
||||
ld hl,systab
|
||||
add hl,de
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl)
|
||||
ex de,hl
|
||||
jp (hl)
|
||||
|
||||
systab:
|
||||
.word e.mon ! ux_indir
|
||||
.word ux_exit
|
||||
.word e.mon ! ux_fork
|
||||
.word ux_read
|
||||
.word ux_write
|
||||
.word ux_open
|
||||
.word ux_close
|
||||
.word e.mon ! ux_wait
|
||||
.word ux_creat
|
||||
.word e.mon ! ux_link
|
||||
.word ux_unlink
|
||||
.word e.mon ! ux_exec
|
||||
.word e.mon ! ux_chdir
|
||||
.word ux_time
|
||||
.word e.mon ! ux_mknod
|
||||
.word e.mon ! ux_chmod
|
||||
.word e.mon ! ux_chown
|
||||
.word e.mon ! ux_break
|
||||
.word e.mon ! ux_stat
|
||||
.word e.mon ! ux_seek
|
||||
.word ux_getpid
|
||||
.word e.mon ! ux_mount
|
||||
.word e.mon ! ux_umount
|
||||
.word e.mon ! ux_setuid
|
||||
.word e.mon ! ux_getuid
|
||||
.word e.mon ! ux_stime
|
||||
.word e.mon ! ux_ptrace
|
||||
.word e.mon ! ux_alarm
|
||||
.word e.mon ! ux_fstat
|
||||
.word e.mon ! ux_pause
|
||||
.word e.mon ! ux_utime
|
||||
.word e.mon ! ux_stty
|
||||
.word e.mon ! ux_gtty
|
||||
.word e.mon ! ux_access
|
||||
.word e.mon ! ux_nice
|
||||
.word ux_ftime
|
||||
.word e.mon ! ux_sync
|
||||
.word e.mon ! ux_kill
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word e.mon ! ux_dup
|
||||
.word e.mon ! ux_pipe
|
||||
.word e.mon ! ux_times
|
||||
.word e.mon ! ux_prof
|
||||
.word e.mon ! ux_unused
|
||||
.word e.mon ! ux_setgid
|
||||
.word e.mon ! ux_getgid
|
||||
.word e.mon ! ux_sig
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word ux_ioctl
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld ! ux_exece
|
||||
.word e.mon ! ux_umask
|
||||
.word e.mon ! ux_chroot
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
|
||||
emptyfile:
|
||||
! searches for a free filestructure
|
||||
! returns pointer in iy, 0 if not found
|
||||
ld ix,filearea
|
||||
ld l,maxfiles
|
||||
1:
|
||||
xor a
|
||||
or (ix+openflag)
|
||||
jr nz,3f
|
||||
ld a,maxfiles+3
|
||||
sub l
|
||||
ld (ix+fildes),a
|
||||
! #ifdef CPM1
|
||||
push iy
|
||||
push ix
|
||||
ld de,-128
|
||||
add ix,de
|
||||
push ix
|
||||
pop de
|
||||
ld c,setdma
|
||||
call bdos
|
||||
pop ix
|
||||
pop iy
|
||||
or a ! to clear C
|
||||
! #endif
|
||||
ret
|
||||
3:
|
||||
ld de,filesize
|
||||
add ix,de
|
||||
dec l
|
||||
jr nz,1b
|
||||
scf
|
||||
ret
|
||||
|
||||
findfile:
|
||||
ld ix,filearea
|
||||
ld de,filesize
|
||||
0:
|
||||
dec a
|
||||
ret m
|
||||
add ix,de
|
||||
jr 0b
|
||||
|
||||
getchar:
|
||||
push iy
|
||||
push de
|
||||
push hl
|
||||
dec (ix+nleft)
|
||||
jp p,0f
|
||||
push ix
|
||||
pop hl
|
||||
ld de,-128
|
||||
add hl,de
|
||||
ld (ix+iopointer),l
|
||||
ld (ix+iopointer+1),h
|
||||
ex de,hl
|
||||
push ix
|
||||
ld c,setdma
|
||||
call bdos
|
||||
! #ifdef CPM1
|
||||
ld c,seqread
|
||||
! #else
|
||||
! ld c,randomread
|
||||
! #endif
|
||||
pop de
|
||||
call bdos
|
||||
or a
|
||||
jr z,1f
|
||||
ld (ix+zcount),0
|
||||
pop hl
|
||||
pop de
|
||||
pop iy
|
||||
scf
|
||||
ret
|
||||
1:
|
||||
inc (ix+position)
|
||||
jr nz,2f
|
||||
inc (ix+position+1)
|
||||
2:
|
||||
ld a,127
|
||||
ld (ix+nleft),a
|
||||
0:
|
||||
ld h,(ix+iopointer+1)
|
||||
ld l,(ix+iopointer)
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
ld (ix+iopointer),l
|
||||
ld (ix+iopointer+1),h
|
||||
pop hl
|
||||
pop de
|
||||
pop iy
|
||||
ret
|
||||
or a
|
||||
|
||||
putchar:
|
||||
push hl
|
||||
ld h,(ix+iopointer+1)
|
||||
ld l,(ix+iopointer)
|
||||
ld (hl),a
|
||||
dec (ix+nleft)
|
||||
jr z,0f
|
||||
inc hl
|
||||
ld (ix+iopointer+1),h
|
||||
ld (ix+iopointer),l
|
||||
pop hl
|
||||
ret
|
||||
0:
|
||||
pop hl
|
||||
flsbuf:
|
||||
push hl
|
||||
push de
|
||||
push iy
|
||||
push ix
|
||||
pop hl
|
||||
ld de,-128
|
||||
add hl,de
|
||||
ld (ix+iopointer+1),h
|
||||
ld (ix+iopointer),l
|
||||
ex de,hl
|
||||
push ix
|
||||
ld c,setdma
|
||||
call bdos
|
||||
pop de
|
||||
! #ifdef CPM1
|
||||
ld c,seqwrite
|
||||
! #else
|
||||
! ld c,randomwrite
|
||||
! #endif
|
||||
call bdos
|
||||
or a
|
||||
jr z,1f
|
||||
pop iy
|
||||
pop de
|
||||
pop hl
|
||||
scf
|
||||
ret
|
||||
1:
|
||||
inc (ix+position)
|
||||
jr nz,2f
|
||||
inc (ix+position+1)
|
||||
2:
|
||||
ld a,128
|
||||
ld (ix+nleft),a
|
||||
ld b,a
|
||||
push ix
|
||||
pop hl
|
||||
ld de,-128
|
||||
add hl,de
|
||||
ld a,26 ! ctrl z
|
||||
1: ld (hl),a
|
||||
inc hl
|
||||
djnz 1b
|
||||
pop iy
|
||||
pop de
|
||||
pop hl
|
||||
or a
|
||||
ret
|
||||
|
||||
parsename:
|
||||
! parses file name pointed to by hl and fills in fcb
|
||||
! of the file pointed to by ix.
|
||||
! recognizes filenames as complicated as 'b:file.zot'
|
||||
! and as simple as 'x'
|
||||
|
||||
push iy
|
||||
push ix
|
||||
pop de
|
||||
xor a
|
||||
push de
|
||||
ld b,36 ! sizeof fcb
|
||||
0: ld (de),a
|
||||
inc de
|
||||
djnz 0b
|
||||
pop de
|
||||
inc hl
|
||||
ld a,(hl)
|
||||
dec hl
|
||||
cp ':' ! drive specified ?
|
||||
jr nz,1f
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
inc hl
|
||||
dec a
|
||||
and 15
|
||||
inc a ! now 1<= a <= 16
|
||||
ld (de),a
|
||||
1: inc de
|
||||
ld b,8 ! filename maximum of 8 characters
|
||||
1: ld a,(hl)
|
||||
or a
|
||||
jr nz,8f
|
||||
dec hl
|
||||
ld a,'.'
|
||||
8:
|
||||
inc hl
|
||||
cp '.'
|
||||
jr z,2f
|
||||
and 0177 ! no parity
|
||||
bit 6,a
|
||||
jr z,9f
|
||||
and 0337 ! UPPER case
|
||||
9:
|
||||
ld (de),a
|
||||
inc de
|
||||
djnz 1b
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
cp '.'
|
||||
jr z,3f
|
||||
ld a,' '
|
||||
ld (de),a
|
||||
inc de
|
||||
ld (de),a
|
||||
inc de
|
||||
ld (de),a
|
||||
pop iy
|
||||
ret ! filenames longer than 8 are truncated
|
||||
2: ld a,' ' ! fill with spaces
|
||||
0: ld (de),a
|
||||
inc de
|
||||
djnz 0b
|
||||
3: ld b,3 ! length of extension
|
||||
1: ld a,(hl)
|
||||
inc hl
|
||||
or a
|
||||
jr z,4f
|
||||
cp 0100
|
||||
jp m,2f
|
||||
and 0137
|
||||
2: ld (de),a
|
||||
inc de
|
||||
djnz 1b
|
||||
pop iy
|
||||
ret
|
||||
4: ld a,' '
|
||||
0: ld (de),a
|
||||
inc de
|
||||
djnz 0b
|
||||
pop iy
|
||||
ret
|
||||
|
||||
! various routines
|
||||
ux_close:
|
||||
pop hl
|
||||
ld a,l
|
||||
sub 3
|
||||
jp m,1f
|
||||
cp maxfiles
|
||||
call m,closefil
|
||||
1: ld hl,0
|
||||
push hl ; jr rtn
|
||||
|
||||
closefil:
|
||||
call findfile
|
||||
ld a,(ix+openflag)
|
||||
or a
|
||||
jr z,3f
|
||||
ld (ix+openflag),0
|
||||
cp 1
|
||||
jr z,2f
|
||||
ld a,(ix+nleft)
|
||||
cp 128
|
||||
jr z,2f
|
||||
call flsbuf
|
||||
2:
|
||||
push iy
|
||||
push ix
|
||||
pop de
|
||||
ld c,close
|
||||
call bdos
|
||||
pop iy
|
||||
3: ret
|
||||
|
||||
ux_ioctl:
|
||||
pop hl
|
||||
ld a,l
|
||||
sub 3
|
||||
jp p,1f
|
||||
pop hl
|
||||
ld a,h
|
||||
cp 't'
|
||||
jr nz,e.mon
|
||||
ld a,l
|
||||
cp 8
|
||||
jr z,tiocgetp
|
||||
cp 9
|
||||
jr z,tiocsetp
|
||||
jr e.mon
|
||||
1: pop hl
|
||||
pop hl
|
||||
ld hl,-1
|
||||
push hl ; jr rtn
|
||||
tiocgetp:
|
||||
pop de
|
||||
ld hl,ttymode
|
||||
2: push bc
|
||||
ld bc,6
|
||||
ldir
|
||||
ld h,b
|
||||
ld l,c
|
||||
pop bc
|
||||
push hl ; jr rtn
|
||||
tiocsetp:
|
||||
pop hl
|
||||
ld de,ttymode
|
||||
jr 2b
|
||||
|
||||
ux_time:
|
||||
call time4
|
||||
rtn: ld ix,(return) ; jp (ix)
|
||||
|
||||
ux_ftime:
|
||||
pop hl
|
||||
ld (retarea+6),hl
|
||||
call time4
|
||||
ld hl,(retarea+6)
|
||||
pop de
|
||||
ld (hl),e
|
||||
inc hl
|
||||
ld (hl),d
|
||||
inc hl
|
||||
pop de
|
||||
ld (hl),e
|
||||
inc hl
|
||||
ld (hl),d
|
||||
inc hl
|
||||
xor a
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
ld ix,(return) ; jp (ix)
|
||||
|
||||
time4:
|
||||
pop hl
|
||||
ld (retarea),iy
|
||||
ld (retarea+2),bc
|
||||
ld (retarea+4),hl
|
||||
ld hl,(timebuf+2)
|
||||
push hl
|
||||
ld hl,(timebuf)
|
||||
push hl
|
||||
ld hl,0
|
||||
push hl
|
||||
ld hl,50
|
||||
push hl
|
||||
call .dvu4
|
||||
ld iy,(retarea)
|
||||
ld bc,(retarea+2)
|
||||
ld hl,(retarea+4)
|
||||
jp (hl)
|
||||
ux_exit:
|
||||
call uxfinish
|
||||
ld c,reset
|
||||
call bdos
|
||||
! no return
|
||||
|
||||
ux_creat:
|
||||
call emptyfile
|
||||
jr c,openfailed
|
||||
pop hl
|
||||
call parsename
|
||||
pop hl ! file mode, not used under CP/M
|
||||
push iy
|
||||
push ix
|
||||
push ix
|
||||
pop de
|
||||
ld c,delete
|
||||
call bdos
|
||||
pop de
|
||||
ld c,makefile
|
||||
call bdos
|
||||
pop iy
|
||||
ld l,1
|
||||
jr afteropen
|
||||
ux_open:
|
||||
call emptyfile
|
||||
jr nc,1f
|
||||
openfailed:
|
||||
pop hl
|
||||
pop hl ! remove params
|
||||
ld hl,EMFILE
|
||||
push hl
|
||||
push hl ; jr rtn
|
||||
1:
|
||||
pop hl ! filename
|
||||
call parsename
|
||||
push iy
|
||||
ld c,open
|
||||
push ix
|
||||
pop de
|
||||
call bdos
|
||||
pop iy
|
||||
pop hl
|
||||
afteropen:
|
||||
inc a
|
||||
jr nz,1f
|
||||
ld hl,ENOENT
|
||||
push hl
|
||||
push hl ; jr rtn
|
||||
1:
|
||||
inc l
|
||||
ld (ix+openflag),l
|
||||
xor a
|
||||
ld (ix+nleft),a
|
||||
ld (ix+zcount),a
|
||||
ld (ix+zsave),26
|
||||
bit 1,l
|
||||
jr z,2f
|
||||
ld (ix+nleft),128
|
||||
2:
|
||||
ld (ix+position),a
|
||||
ld (ix+position+1),a
|
||||
push ix
|
||||
pop hl
|
||||
push bc
|
||||
ld b,128
|
||||
3: dec hl
|
||||
ld (hl),26
|
||||
djnz 3b
|
||||
pop bc
|
||||
ld (ix+iopointer+1),h
|
||||
ld (ix+iopointer),l
|
||||
ld h,a
|
||||
ld l,(ix+fildes)
|
||||
push hl
|
||||
ld l,a
|
||||
push hl ; jr rtn
|
||||
|
||||
ux_read:
|
||||
pop hl
|
||||
ld a,l
|
||||
sub 3
|
||||
jp p,readfile
|
||||
ld a,(ttymode+4)
|
||||
bit 5,a
|
||||
jr z,1f ! not raw
|
||||
push iy
|
||||
! #ifdef CPM1
|
||||
!raw echo interface
|
||||
ld c,consolein
|
||||
call bdos
|
||||
! #else
|
||||
! !no echo interface
|
||||
! 4:
|
||||
! ld c,diconio
|
||||
! ld e,0xff
|
||||
! call bdos
|
||||
! or a
|
||||
! jr z,4b
|
||||
!end of no echo interface
|
||||
! #endif
|
||||
pop iy
|
||||
pop hl
|
||||
ld (hl),a
|
||||
pop hl
|
||||
ld hl,1
|
||||
push hl
|
||||
ld hl,0
|
||||
push hl ; jr rtn
|
||||
1:
|
||||
ld hl,sibuf+1 ! read from console assumed
|
||||
dec (hl)
|
||||
jp p,2f
|
||||
dec hl ! go read console line
|
||||
ld (hl),80 ! max line length
|
||||
push iy
|
||||
push hl
|
||||
ld c,readconsole
|
||||
ex de,hl
|
||||
call bdos
|
||||
ld c,writeconsole
|
||||
ld e,'\n'
|
||||
call bdos
|
||||
pop hl
|
||||
pop iy
|
||||
inc hl
|
||||
inc (hl)
|
||||
ld (siptr),hl ! ready for transfer
|
||||
push hl
|
||||
ld e,(hl)
|
||||
ld d,0
|
||||
add hl,de
|
||||
ld (hl),'\r'
|
||||
inc hl
|
||||
ld (hl),'\n'
|
||||
pop hl
|
||||
2:
|
||||
push bc
|
||||
pop ix
|
||||
ld b,(hl)
|
||||
inc b ! bytes remaining
|
||||
pop hl ! copy to
|
||||
pop de ! bytes wanted (probably 512)
|
||||
push ix
|
||||
ld ix,(siptr) ! copy from
|
||||
xor a ! find out minimum of ramaining and wanted
|
||||
or d
|
||||
jr nz,3f ! more than 255 wanted (forget that)
|
||||
ld a,b
|
||||
cp e
|
||||
jp m,3f ! not enough remaining
|
||||
ld b,e
|
||||
3:
|
||||
ld c,b ! keep copy
|
||||
0:
|
||||
inc ix
|
||||
ld a,(ix)
|
||||
ld (hl),a
|
||||
inc hl
|
||||
djnz 0b
|
||||
ld a,(sibuf+1)
|
||||
sub c
|
||||
inc a
|
||||
ld (sibuf+1),a
|
||||
ld (siptr),ix
|
||||
pop hl
|
||||
push bc
|
||||
ld c,b
|
||||
push bc ! load 0
|
||||
ld b,h
|
||||
ld c,l
|
||||
ld ix,(return) ; jp (ix)
|
||||
readfile:
|
||||
call findfile
|
||||
pop de
|
||||
pop hl ! count
|
||||
push bc
|
||||
ld bc,0
|
||||
0:
|
||||
xor a
|
||||
or l
|
||||
jr z,1f
|
||||
dec l
|
||||
3:
|
||||
! warning: this may not work if zcount overflows
|
||||
ld a,(ix+zcount)
|
||||
or a
|
||||
jr nz,5f
|
||||
ld a,(ix+zsave)
|
||||
cp 26
|
||||
jr z,4f
|
||||
ld (ix+zsave),26
|
||||
jr 8f
|
||||
4:
|
||||
call getchar
|
||||
jr c,2f
|
||||
ld (de),a
|
||||
sub 26 ! CTRL-Z
|
||||
jr z,7f
|
||||
ld a,(ix+zcount)
|
||||
or a
|
||||
jr z,6f
|
||||
ld a,(de)
|
||||
ld (ix+zsave),a
|
||||
5:
|
||||
ld a,26
|
||||
dec (ix+zcount)
|
||||
8:
|
||||
ld (de),a
|
||||
6:
|
||||
inc de
|
||||
inc bc
|
||||
jr 0b
|
||||
1:
|
||||
dec l
|
||||
dec h
|
||||
jp p,3b
|
||||
2:
|
||||
pop hl
|
||||
push bc
|
||||
ld b,h
|
||||
ld c,l
|
||||
ld hl,0
|
||||
push hl ; jr rtn
|
||||
7:
|
||||
inc (ix+zcount)
|
||||
jr 4b
|
||||
|
||||
ux_write:
|
||||
pop hl
|
||||
ld a,l
|
||||
sub 3
|
||||
jp p,writefile
|
||||
pop hl ! buffer address
|
||||
pop de ! count
|
||||
push de
|
||||
ld ix,0
|
||||
push ix
|
||||
push bc
|
||||
ld b,e ! count now in 'db'
|
||||
0:
|
||||
ld a,b
|
||||
or a
|
||||
jr nz,1f
|
||||
ld a,d
|
||||
or a
|
||||
jr nz,2f
|
||||
pop bc
|
||||
ld ix,(return) ; jp (ix)
|
||||
2:
|
||||
dec d
|
||||
1:
|
||||
dec b
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
ld c,writeconsole
|
||||
call bdos
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
jr 0b
|
||||
writefile:
|
||||
call findfile
|
||||
pop de
|
||||
pop hl ! count
|
||||
push bc
|
||||
ld bc,0
|
||||
0:
|
||||
xor a
|
||||
or l
|
||||
jr z,1f
|
||||
dec l
|
||||
3:
|
||||
ld a,(de)
|
||||
inc de
|
||||
call putchar
|
||||
jr c,4f
|
||||
inc bc
|
||||
jr 0b
|
||||
1:
|
||||
dec l
|
||||
dec h
|
||||
jp p,3b
|
||||
ld ix,0
|
||||
2:
|
||||
pop hl
|
||||
push bc
|
||||
ld b,h
|
||||
ld c,l
|
||||
push ix
|
||||
ld ix,(return) ; jp (ix)
|
||||
4:
|
||||
ld ix,ENOSPC
|
||||
jr 2b
|
||||
|
||||
ux_unlink:
|
||||
pop hl
|
||||
ld ix,fcb
|
||||
call parsename
|
||||
push bc
|
||||
ld c,delete
|
||||
ld de,fcb
|
||||
call bdos
|
||||
pop bc
|
||||
inc a
|
||||
jr nz,1f
|
||||
ld hl,ENOENT
|
||||
push hl ; jr rtn
|
||||
1:
|
||||
ld hl,0
|
||||
push hl ; jr rtn
|
||||
|
||||
ux_getpid:
|
||||
ld hl,12345 ! nice number
|
||||
push hl ; jr rtn
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
retarea: .word 0 ! base of buffer for result values (max 8 bytes)
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
trapproc:
|
||||
.word 0
|
||||
|
||||
nextp: .byte 0
|
||||
|
||||
header:
|
||||
ntext: .word 0
|
||||
ndata: .word 0
|
||||
nproc: .word 0
|
||||
entry: .word 0
|
||||
nline: .word 0
|
||||
|
||||
hp: .word 0
|
||||
pb: .word 0
|
||||
pd: .word 0
|
102
mach/z80/libmon/mon.s
Normal file
102
mach/z80/libmon/mon.s
Normal file
|
@ -0,0 +1,102 @@
|
|||
.define .mon
|
||||
|
||||
! Monitor call
|
||||
! Expects on stack: monitor call number
|
||||
! parameters
|
||||
! Implemented are the following monitor calls:
|
||||
! number 1: exit
|
||||
! number 3: read
|
||||
! number 4: write
|
||||
! number 5: open
|
||||
! number 6: close
|
||||
! number 54: ioctl
|
||||
! If called with a number of a call that is not implemented,
|
||||
! a trap is generated.
|
||||
|
||||
.mon:
|
||||
pop ix ! returnaddress
|
||||
|
||||
pop hl ! monitor call number
|
||||
ld a,l
|
||||
cp 1
|
||||
jp z,monexit ! is it an exit?
|
||||
cp 3
|
||||
jp z,monread ! is it a read?
|
||||
cp 4
|
||||
jp z,monwrite ! is it a write?
|
||||
cp 5
|
||||
jp z,monopen ! is it an open?
|
||||
cp 6
|
||||
jp z,monclose ! is it a close?
|
||||
cp 54
|
||||
jp z,monioctl
|
||||
jp ebadmon ! trap
|
||||
|
||||
monexit:
|
||||
jp 0x38
|
||||
|
||||
monread:
|
||||
pop hl ! file-descriptor, not used
|
||||
pop hl ! hl = pointer to output buffer
|
||||
pop de ! de = number of bytes to be read
|
||||
ld bc,0 ! bc will contain the number of bytes actually read
|
||||
1: ld a,d
|
||||
or e
|
||||
jr z,2f
|
||||
call getchar
|
||||
push af
|
||||
call putchar ! echo character
|
||||
pop af
|
||||
ld (hl),a
|
||||
inc hl
|
||||
inc bc
|
||||
dec de
|
||||
cp 0x0A ! is it a newline?
|
||||
jp nz,1b
|
||||
2: push bc
|
||||
ld hl,0
|
||||
push hl
|
||||
jp (ix)
|
||||
|
||||
monwrite:
|
||||
pop hl ! file-descriptor, not used
|
||||
pop hl ! hl = pointer to output buffer
|
||||
pop de ! de = number of bytes
|
||||
push de
|
||||
1: ld a,e
|
||||
or d
|
||||
jr z,2f
|
||||
ld a,(hl)
|
||||
call putchar
|
||||
inc hl
|
||||
dec de
|
||||
jp 1b
|
||||
|
||||
2: push de ! no error
|
||||
jp (ix)
|
||||
|
||||
|
||||
monopen:
|
||||
pop hl ! pointer to string
|
||||
pop hl ! flag
|
||||
ld hl,-1
|
||||
push hl ! push file descriptor
|
||||
push hl ! push error code twice
|
||||
push hl
|
||||
jp (ix)
|
||||
|
||||
monclose:
|
||||
ex (sp),hl ! pop file descriptor and push error code
|
||||
pop hl ! file descriptor
|
||||
ld hl,-1
|
||||
push hl ! push error code twice
|
||||
push hl
|
||||
jp (ix)
|
||||
|
||||
monioctl:
|
||||
pop hl ! file descriptor
|
||||
pop hl ! request
|
||||
ld hl,0
|
||||
ex (sp),hl ! remove argp and push error code
|
||||
jp (ix)
|
||||
|
28
mach/z80/libmon/putchr.nas.s
Normal file
28
mach/z80/libmon/putchr.nas.s
Normal file
|
@ -0,0 +1,28 @@
|
|||
.define putchr
|
||||
! output routine in monitor
|
||||
CRT = 0x013B
|
||||
! output a charcter
|
||||
! entry: ascii character in a
|
||||
putchr:
|
||||
push hl
|
||||
push bc
|
||||
ld hl,tab
|
||||
ld b,5
|
||||
1: cp (hl)
|
||||
jr z,fetch
|
||||
inc hl
|
||||
inc hl
|
||||
djnz 1b
|
||||
2: call CRT
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
fetch: inc hl
|
||||
ld a,(hl)
|
||||
jr 2b
|
||||
! conversion table for nascom characters
|
||||
tab: .byte 0x0D,0x00
|
||||
.byte 0x1B,0x1E
|
||||
.byte 0x08,0x1D
|
||||
.byte 0x0A,0x1F
|
||||
.byte 0x7F,0x00
|
21
mach/z80/libmon/putchr.s
Normal file
21
mach/z80/libmon/putchr.s
Normal file
|
@ -0,0 +1,21 @@
|
|||
.define putchr
|
||||
|
||||
putchr:
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
cp 0x0A
|
||||
jr nz,1f
|
||||
ld a,0x1F
|
||||
1:
|
||||
ld c,a
|
||||
2:
|
||||
in a,0xF1
|
||||
and 4
|
||||
jr z,2b
|
||||
ld a,c
|
||||
out 0xF0,a
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
197
mach/z80/libmon/subr.s
Normal file
197
mach/z80/libmon/subr.s
Normal file
|
@ -0,0 +1,197 @@
|
|||
.define _read,_write,_ioctl,_getpid,_open,_close,_exit,_errno
|
||||
_read:
|
||||
ld (savebc),bc
|
||||
push af
|
||||
pop bc
|
||||
ld (saveaf),bc ! save all registers in savereg
|
||||
ld (savede),de
|
||||
ld (savehl),hl
|
||||
ld (saveix),ix
|
||||
ex (sp),hl ! return address in hl
|
||||
pop bc ! skip return address
|
||||
pop bc ! get fd
|
||||
ld a,b ! check fd = 0
|
||||
or c
|
||||
jr nz,errrd
|
||||
pop de ! get buffer
|
||||
pop bc ! get count
|
||||
ld ix,0 ! reset counter
|
||||
push bc
|
||||
push de
|
||||
push ix
|
||||
push hl ! return address
|
||||
ex de,hl ! buffer to hl
|
||||
1: ld a,b
|
||||
or c
|
||||
jr z,done ! done if count = 0
|
||||
call getchr
|
||||
ld (hl),a
|
||||
inc hl ! increment pointer
|
||||
inc ix ! increment char counter
|
||||
dec bc ! decrement count
|
||||
cp 0xA
|
||||
jr nz,1b ! done if char = CR
|
||||
done:
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
ret
|
||||
errrd:
|
||||
push bc
|
||||
push hl ! return address
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
ld ix,-1
|
||||
ret
|
||||
|
||||
_write:
|
||||
ld (savebc),bc
|
||||
push af
|
||||
pop bc
|
||||
ld (saveaf),bc ! save all registers in savereg
|
||||
ld (savede),de
|
||||
ld (savehl),hl
|
||||
ld (saveix),ix
|
||||
ex (sp),hl ! return address in hl
|
||||
pop de ! skip return address
|
||||
pop de ! get fd
|
||||
ld a,e ! check for fd = 1
|
||||
cp 1
|
||||
jr nz,errwr
|
||||
ld a,d
|
||||
or a
|
||||
jr nz,errwr
|
||||
pop de ! buffer in de
|
||||
pop bc ! count in bc
|
||||
push bc
|
||||
push de
|
||||
push de
|
||||
push hl
|
||||
ex de,hl ! buffer in hl
|
||||
ld e,c
|
||||
ld d,b ! count also in de
|
||||
1: ld a,b
|
||||
or c
|
||||
jr z,exit
|
||||
ld a,(hl)
|
||||
call putchr
|
||||
inc hl
|
||||
dec bc
|
||||
jr 1b
|
||||
errwr:
|
||||
push de
|
||||
push hl
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
ld ix,-1 ! error in fd
|
||||
ret
|
||||
exit:
|
||||
push de ! count on stack
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
pop ix ! return count to caller
|
||||
ret
|
||||
|
||||
_ioctl:
|
||||
ret
|
||||
_getpid:
|
||||
ret
|
||||
|
||||
! open return a file descriptor (0,1,2)
|
||||
! depending on 'mode'
|
||||
! mode 2 doesn't work!!
|
||||
_open:
|
||||
ld (savebc),bc
|
||||
push af
|
||||
pop bc
|
||||
ld (saveaf),bc ! save all registers in savereg
|
||||
ld (savede),de
|
||||
ld (savehl),hl
|
||||
ld (saveix),ix
|
||||
pop bc ! return address
|
||||
pop de ! name pointer
|
||||
pop ix ! mode (0 for read,
|
||||
! 1 for write)
|
||||
push ix
|
||||
push de
|
||||
push bc
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
ret ! return fd = 0 for read
|
||||
! fd = 1 for write
|
||||
|
||||
_close:
|
||||
ld ix,0 ! return succes
|
||||
ret
|
||||
_exit:
|
||||
jp 0x38
|
||||
.data
|
||||
_errno:
|
||||
.word 0
|
||||
! output routine in monitor
|
||||
CRT = 0x013B
|
||||
! output a charcter
|
||||
! entry: ascii character in a
|
||||
.text
|
||||
!putchr:
|
||||
! push hl
|
||||
! push bc
|
||||
! ld hl,tab
|
||||
! ld b,5
|
||||
!1: cp (hl)
|
||||
! jr z,fetch
|
||||
! inc hl
|
||||
! inc hl
|
||||
! djnz 1b
|
||||
!2: call CRT
|
||||
! pop bc
|
||||
! pop hl
|
||||
! ret
|
||||
!fetch: inc hl
|
||||
! ld a,(hl)
|
||||
! jr 2b
|
||||
!! conversion table for nascom characters
|
||||
!tab: .byte 0x0D,0x00
|
||||
! .byte 0x1B,0x1E
|
||||
! .byte 0x08,0x1D
|
||||
! .byte 0x0A,0x1F
|
||||
! .byte 0x7F,0x00
|
||||
|
||||
KBD = 0x69
|
||||
! get character from keyboard
|
||||
getchr:
|
||||
call KBD
|
||||
jr nc,getchr
|
||||
cp 0x1F
|
||||
jr z,CR
|
||||
cp 0x1D
|
||||
jr z,BS
|
||||
ret
|
||||
CR: ld a,0xA
|
||||
ret
|
||||
BS: ld a,0x8
|
||||
ret
|
28
mach/z80/libsys/Makefile
Normal file
28
mach/z80/libsys/Makefile
Normal file
|
@ -0,0 +1,28 @@
|
|||
TAIL=tail.hermac
|
||||
# Other possibilities are: tail.nascom and tail.cpm
|
||||
|
||||
all: tail.cpm tail.nascom tail.hermac
|
||||
|
||||
install: $(TAIL)
|
||||
../../install head_em.s head_em
|
||||
../../install $(TAIL) tail_sys
|
||||
|
||||
cmp: $(TAIL)
|
||||
-../../compare head_em.s head_em
|
||||
-../../compare $(TAIL) tail_sys
|
||||
|
||||
tail.cpm: mon.cpm.s
|
||||
@echo Warning: untested, this is an example
|
||||
arch cr tail.cpm mon.cpm.s
|
||||
|
||||
tail.nascom: mon.s putchr.nas.s
|
||||
arch cr tail.nascom mon.s putchr.nas.s
|
||||
|
||||
tail.hermac: mon.s char.her.s
|
||||
arch cr tail.hermac mon.s char.her.s
|
||||
|
||||
opr:
|
||||
make pr | opr
|
||||
pr:
|
||||
@pr `pwd`/Makefile `pwd`/head_em.s
|
||||
@pr `pwd`/subr.s `pwd`/mon.s `pwd`/mon.cpm.s `pwd`/putchr.s `pwd`/putchr.nas.s `pwd`/char.her.s
|
12
mach/z80/libsys/README
Normal file
12
mach/z80/libsys/README
Normal file
|
@ -0,0 +1,12 @@
|
|||
This directory contains files for three different environments:
|
||||
- The Hermac computer.
|
||||
- The Nascom computer.
|
||||
- A CPM system.
|
||||
|
||||
The default system used is the Hermac on which this software was
|
||||
tested. The Nascom environment has been known to work too.
|
||||
The CPM files are included as an example only. These have never
|
||||
been tested.
|
||||
|
||||
The definition of TAIL in the Makefile decides which environment
|
||||
you use.
|
31
mach/z80/libsys/char.her.s
Normal file
31
mach/z80/libsys/char.her.s
Normal file
|
@ -0,0 +1,31 @@
|
|||
.define getchar, putchar
|
||||
|
||||
! These getchar and putchar routines can be used for HERMAC computer
|
||||
|
||||
! Read a character from HERMAC-monitor
|
||||
! Character is returned in a-reg
|
||||
|
||||
getchar:
|
||||
in a,0xF1
|
||||
and 1
|
||||
jp z,getchar
|
||||
in a,0xF0
|
||||
cp 0x0D
|
||||
jp nz,1f
|
||||
ld a,0x0A
|
||||
1: ret
|
||||
|
||||
! Write character on HERMAC monitor
|
||||
! Assumes character in a-reg
|
||||
|
||||
putchar:
|
||||
cp 0x0A
|
||||
jp nz,1f
|
||||
ld a,0x1F
|
||||
1: push af
|
||||
2: in a,0xF1
|
||||
and 4
|
||||
jp z,2b
|
||||
pop af
|
||||
out 0xF0,a
|
||||
ret
|
80
mach/z80/libsys/head_em.s
Normal file
80
mach/z80/libsys/head_em.s
Normal file
|
@ -0,0 +1,80 @@
|
|||
.define EARRAY,ERANGE,EILLINS,EILLSIZE,ECASE,EMON,EHEAP
|
||||
.define hol0,trapproc,trpim,argv,hp,.reghp,envp,begbss,ignmask
|
||||
.define savebc,savede,savehl,saveix,saveaf,saveiy,ebadmon
|
||||
EARRAY = 0
|
||||
ERANGE = 1
|
||||
EHEAP = 17
|
||||
EILLINS=18
|
||||
EILLSIZE=19
|
||||
ECASE=20
|
||||
EMON=25
|
||||
ebadmon=25
|
||||
|
||||
|
||||
.base 0x1000
|
||||
.text
|
||||
|
||||
! clear .bss
|
||||
ld sp,0x7ffe !address of fbase
|
||||
ld de,endbss
|
||||
ld h,d
|
||||
ld l,e
|
||||
ld bc,begbss
|
||||
sbc hl,bc
|
||||
ld a,h
|
||||
or l
|
||||
jr z,1f
|
||||
2:
|
||||
xor a
|
||||
ld (de),a
|
||||
dec de
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,2b
|
||||
1: ! hl == 0
|
||||
|
||||
ld bc,envp
|
||||
push bc
|
||||
ld bc,argv
|
||||
push bc
|
||||
ld bc,1
|
||||
push bc
|
||||
call _m_a_i_n
|
||||
|
||||
jp 0x20
|
||||
|
||||
.bss
|
||||
begbss:
|
||||
.data
|
||||
hol0:
|
||||
.word 0,0
|
||||
.word 0,0
|
||||
saveaf:
|
||||
.word 0
|
||||
savebc:
|
||||
.word 0
|
||||
savede:
|
||||
.word 0
|
||||
savehl:
|
||||
.word 0
|
||||
saveix:
|
||||
.word 0
|
||||
saveiy:
|
||||
.word 0
|
||||
ignmask:
|
||||
.word 0
|
||||
hp:
|
||||
.word 0
|
||||
trapproc:
|
||||
.word 0
|
||||
trpim:
|
||||
.word 0
|
||||
argv:
|
||||
.word 3f
|
||||
envp:
|
||||
.word 0
|
||||
3:
|
||||
.asciz 'PROGRAM'
|
||||
.reghp:
|
||||
.word endbss
|
924
mach/z80/libsys/mon.cpm.s
Normal file
924
mach/z80/libsys/mon.cpm.s
Normal file
|
@ -0,0 +1,924 @@
|
|||
.define .mon
|
||||
.define uxfinish
|
||||
|
||||
! monitor instruction
|
||||
! a small collection of UNIX system calls implemented under CP/M
|
||||
|
||||
! ux_indir=e.mon
|
||||
! ux_fork=e.mon
|
||||
! ux_wait=e.mon
|
||||
! ux_link=e.mon
|
||||
! ux_exec=e.mon
|
||||
! ux_chdir=e.mon
|
||||
! ux_mknod=e.mon
|
||||
! ux_chmod=e.mon
|
||||
! ux_chown=e.mon
|
||||
! ux_break=e.mon
|
||||
! ux_stat=e.mon
|
||||
! ux_seek=e.mon
|
||||
! ux_mount=e.mon
|
||||
! ux_umount=e.mon
|
||||
! ux_setuid=e.mon
|
||||
! ux_getuid=e.mon
|
||||
! ux_stime=e.mon
|
||||
! ux_ptrace=e.mon
|
||||
! ux_alarm=e.mon
|
||||
! ux_fstat=e.mon
|
||||
! ux_pause=e.mon
|
||||
! ux_utime=e.mon
|
||||
! ux_stty=e.mon
|
||||
! ux_gtty=e.mon
|
||||
! ux_access=e.mon
|
||||
! ux_nice=e.mon
|
||||
! ux_sync=e.mon
|
||||
! ux_kill=e.mon
|
||||
! ux_dup=e.mon
|
||||
! ux_pipe=e.mon
|
||||
! ux_times=e.mon
|
||||
! ux_prof=e.mon
|
||||
! ux_unused=e.mon
|
||||
! ux_setgid=e.mon
|
||||
! ux_getgid=e.mon
|
||||
! ux_sig=e.mon
|
||||
! ux_umask=e.mon
|
||||
! ux_chroot=e.mon
|
||||
|
||||
EPERM = 1
|
||||
ENOENT = 2
|
||||
ESRCH = 3
|
||||
EINTR = 4
|
||||
EIO = 5
|
||||
ENXIO = 6
|
||||
E2BIG = 7
|
||||
ENOEXEC = 8
|
||||
EBADF = 9
|
||||
ECHILD = 10
|
||||
EAGAIN = 11
|
||||
ENOMEM = 12
|
||||
EACCES = 13
|
||||
EFAULT = 14
|
||||
ENOTBLK = 15
|
||||
EBUSY = 16
|
||||
EEXIST = 17
|
||||
EXDEV = 18
|
||||
ENODEV = 19
|
||||
ENOTDIR = 20
|
||||
EISDIR = 21
|
||||
EINVAL = 22
|
||||
ENFILE = 23
|
||||
EMFILE = 24
|
||||
ENOTTY = 25
|
||||
ETXTBSY = 26
|
||||
EFBIG = 27
|
||||
ENOSPC = 28
|
||||
ESPIPE = 29
|
||||
EROFS = 30
|
||||
EMLINK = 31
|
||||
EPIPE = 32
|
||||
EDOM = 33
|
||||
! Structure of filearea maintained by this implementation
|
||||
! First iobuffer of 128 bytes
|
||||
! Then the fcb area of 36 bytes
|
||||
! The number of bytes left in the buffer, 1 byte
|
||||
! The iopointer into the buffer, 2 bytes
|
||||
! The openflag 0 unused, 1 reading, 2 writing, 1 byte
|
||||
! The filedescriptor starting at 3, 1 byte
|
||||
! The number of CTRL-Zs that have been absorbed, 1 byte
|
||||
! The byte read after a sequence of CTRL-Zs, 1 byte
|
||||
|
||||
maxfiles=8
|
||||
filesize=128+36+1+2+1+1+1+1
|
||||
|
||||
filefcb=0 ! pointers point to fcb
|
||||
position=33
|
||||
nleft=36
|
||||
iopointer=37
|
||||
openflag=39
|
||||
fildes=40
|
||||
zcount=41
|
||||
zsave=42
|
||||
|
||||
.errnz filefcb
|
||||
|
||||
0: .space maxfiles*filesize
|
||||
filearea = 0b+128
|
||||
sibuf:
|
||||
.word 0
|
||||
.space 82
|
||||
siptr: .space 2
|
||||
saveargs:
|
||||
.space 128
|
||||
argc: .space 2
|
||||
ttymode:.byte 9,9,8,21;.short 06310+RAW*040 ! raw = 040
|
||||
|
||||
return:
|
||||
.word 0,0
|
||||
uxinit:
|
||||
xor a
|
||||
ld c,maxfiles
|
||||
ld hl,0b
|
||||
1: ld b,filesize
|
||||
2: ld (hl),a
|
||||
inc hl
|
||||
djnz 2b
|
||||
dec c
|
||||
jr nz,1b
|
||||
ret
|
||||
|
||||
uxfinish:
|
||||
ld a,maxfiles-1
|
||||
1: push af
|
||||
call closefil
|
||||
pop af
|
||||
dec a
|
||||
cp 0377
|
||||
jr nz,1b
|
||||
ret
|
||||
|
||||
.mon:
|
||||
pop ix
|
||||
ld (return),ix ! return adres
|
||||
pop de ! system call number
|
||||
xor a
|
||||
or d
|
||||
jr nz,unimpld ! too big
|
||||
ld a,e
|
||||
and 0300 ! only 64 system calls
|
||||
jr nz,unimpld
|
||||
sla e
|
||||
ld hl,systab
|
||||
add hl,de
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl)
|
||||
ex de,hl
|
||||
jp (hl)
|
||||
|
||||
systab:
|
||||
.word e.mon ! ux_indir
|
||||
.word ux_exit
|
||||
.word e.mon ! ux_fork
|
||||
.word ux_read
|
||||
.word ux_write
|
||||
.word ux_open
|
||||
.word ux_close
|
||||
.word e.mon ! ux_wait
|
||||
.word ux_creat
|
||||
.word e.mon ! ux_link
|
||||
.word ux_unlink
|
||||
.word e.mon ! ux_exec
|
||||
.word e.mon ! ux_chdir
|
||||
.word ux_time
|
||||
.word e.mon ! ux_mknod
|
||||
.word e.mon ! ux_chmod
|
||||
.word e.mon ! ux_chown
|
||||
.word e.mon ! ux_break
|
||||
.word e.mon ! ux_stat
|
||||
.word e.mon ! ux_seek
|
||||
.word ux_getpid
|
||||
.word e.mon ! ux_mount
|
||||
.word e.mon ! ux_umount
|
||||
.word e.mon ! ux_setuid
|
||||
.word e.mon ! ux_getuid
|
||||
.word e.mon ! ux_stime
|
||||
.word e.mon ! ux_ptrace
|
||||
.word e.mon ! ux_alarm
|
||||
.word e.mon ! ux_fstat
|
||||
.word e.mon ! ux_pause
|
||||
.word e.mon ! ux_utime
|
||||
.word e.mon ! ux_stty
|
||||
.word e.mon ! ux_gtty
|
||||
.word e.mon ! ux_access
|
||||
.word e.mon ! ux_nice
|
||||
.word ux_ftime
|
||||
.word e.mon ! ux_sync
|
||||
.word e.mon ! ux_kill
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word e.mon ! ux_dup
|
||||
.word e.mon ! ux_pipe
|
||||
.word e.mon ! ux_times
|
||||
.word e.mon ! ux_prof
|
||||
.word e.mon ! ux_unused
|
||||
.word e.mon ! ux_setgid
|
||||
.word e.mon ! ux_getgid
|
||||
.word e.mon ! ux_sig
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word ux_ioctl
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
.word unimpld ! ux_exece
|
||||
.word e.mon ! ux_umask
|
||||
.word e.mon ! ux_chroot
|
||||
.word unimpld
|
||||
.word unimpld
|
||||
|
||||
emptyfile:
|
||||
! searches for a free filestructure
|
||||
! returns pointer in iy, 0 if not found
|
||||
ld ix,filearea
|
||||
ld l,maxfiles
|
||||
1:
|
||||
xor a
|
||||
or (ix+openflag)
|
||||
jr nz,3f
|
||||
ld a,maxfiles+3
|
||||
sub l
|
||||
ld (ix+fildes),a
|
||||
! #ifdef CPM1
|
||||
push iy
|
||||
push ix
|
||||
ld de,-128
|
||||
add ix,de
|
||||
push ix
|
||||
pop de
|
||||
ld c,setdma
|
||||
call bdos
|
||||
pop ix
|
||||
pop iy
|
||||
or a ! to clear C
|
||||
! #endif
|
||||
ret
|
||||
3:
|
||||
ld de,filesize
|
||||
add ix,de
|
||||
dec l
|
||||
jr nz,1b
|
||||
scf
|
||||
ret
|
||||
|
||||
findfile:
|
||||
ld ix,filearea
|
||||
ld de,filesize
|
||||
0:
|
||||
dec a
|
||||
ret m
|
||||
add ix,de
|
||||
jr 0b
|
||||
|
||||
getchar:
|
||||
push iy
|
||||
push de
|
||||
push hl
|
||||
dec (ix+nleft)
|
||||
jp p,0f
|
||||
push ix
|
||||
pop hl
|
||||
ld de,-128
|
||||
add hl,de
|
||||
ld (ix+iopointer),l
|
||||
ld (ix+iopointer+1),h
|
||||
ex de,hl
|
||||
push ix
|
||||
ld c,setdma
|
||||
call bdos
|
||||
! #ifdef CPM1
|
||||
ld c,seqread
|
||||
! #else
|
||||
! ld c,randomread
|
||||
! #endif
|
||||
pop de
|
||||
call bdos
|
||||
or a
|
||||
jr z,1f
|
||||
ld (ix+zcount),0
|
||||
pop hl
|
||||
pop de
|
||||
pop iy
|
||||
scf
|
||||
ret
|
||||
1:
|
||||
inc (ix+position)
|
||||
jr nz,2f
|
||||
inc (ix+position+1)
|
||||
2:
|
||||
ld a,127
|
||||
ld (ix+nleft),a
|
||||
0:
|
||||
ld h,(ix+iopointer+1)
|
||||
ld l,(ix+iopointer)
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
ld (ix+iopointer),l
|
||||
ld (ix+iopointer+1),h
|
||||
pop hl
|
||||
pop de
|
||||
pop iy
|
||||
ret
|
||||
or a
|
||||
|
||||
putchar:
|
||||
push hl
|
||||
ld h,(ix+iopointer+1)
|
||||
ld l,(ix+iopointer)
|
||||
ld (hl),a
|
||||
dec (ix+nleft)
|
||||
jr z,0f
|
||||
inc hl
|
||||
ld (ix+iopointer+1),h
|
||||
ld (ix+iopointer),l
|
||||
pop hl
|
||||
ret
|
||||
0:
|
||||
pop hl
|
||||
flsbuf:
|
||||
push hl
|
||||
push de
|
||||
push iy
|
||||
push ix
|
||||
pop hl
|
||||
ld de,-128
|
||||
add hl,de
|
||||
ld (ix+iopointer+1),h
|
||||
ld (ix+iopointer),l
|
||||
ex de,hl
|
||||
push ix
|
||||
ld c,setdma
|
||||
call bdos
|
||||
pop de
|
||||
! #ifdef CPM1
|
||||
ld c,seqwrite
|
||||
! #else
|
||||
! ld c,randomwrite
|
||||
! #endif
|
||||
call bdos
|
||||
or a
|
||||
jr z,1f
|
||||
pop iy
|
||||
pop de
|
||||
pop hl
|
||||
scf
|
||||
ret
|
||||
1:
|
||||
inc (ix+position)
|
||||
jr nz,2f
|
||||
inc (ix+position+1)
|
||||
2:
|
||||
ld a,128
|
||||
ld (ix+nleft),a
|
||||
ld b,a
|
||||
push ix
|
||||
pop hl
|
||||
ld de,-128
|
||||
add hl,de
|
||||
ld a,26 ! ctrl z
|
||||
1: ld (hl),a
|
||||
inc hl
|
||||
djnz 1b
|
||||
pop iy
|
||||
pop de
|
||||
pop hl
|
||||
or a
|
||||
ret
|
||||
|
||||
parsename:
|
||||
! parses file name pointed to by hl and fills in fcb
|
||||
! of the file pointed to by ix.
|
||||
! recognizes filenames as complicated as 'b:file.zot'
|
||||
! and as simple as 'x'
|
||||
|
||||
push iy
|
||||
push ix
|
||||
pop de
|
||||
xor a
|
||||
push de
|
||||
ld b,36 ! sizeof fcb
|
||||
0: ld (de),a
|
||||
inc de
|
||||
djnz 0b
|
||||
pop de
|
||||
inc hl
|
||||
ld a,(hl)
|
||||
dec hl
|
||||
cp ':' ! drive specified ?
|
||||
jr nz,1f
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
inc hl
|
||||
dec a
|
||||
and 15
|
||||
inc a ! now 1<= a <= 16
|
||||
ld (de),a
|
||||
1: inc de
|
||||
ld b,8 ! filename maximum of 8 characters
|
||||
1: ld a,(hl)
|
||||
or a
|
||||
jr nz,8f
|
||||
dec hl
|
||||
ld a,'.'
|
||||
8:
|
||||
inc hl
|
||||
cp '.'
|
||||
jr z,2f
|
||||
and 0177 ! no parity
|
||||
bit 6,a
|
||||
jr z,9f
|
||||
and 0337 ! UPPER case
|
||||
9:
|
||||
ld (de),a
|
||||
inc de
|
||||
djnz 1b
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
cp '.'
|
||||
jr z,3f
|
||||
ld a,' '
|
||||
ld (de),a
|
||||
inc de
|
||||
ld (de),a
|
||||
inc de
|
||||
ld (de),a
|
||||
pop iy
|
||||
ret ! filenames longer than 8 are truncated
|
||||
2: ld a,' ' ! fill with spaces
|
||||
0: ld (de),a
|
||||
inc de
|
||||
djnz 0b
|
||||
3: ld b,3 ! length of extension
|
||||
1: ld a,(hl)
|
||||
inc hl
|
||||
or a
|
||||
jr z,4f
|
||||
cp 0100
|
||||
jp m,2f
|
||||
and 0137
|
||||
2: ld (de),a
|
||||
inc de
|
||||
djnz 1b
|
||||
pop iy
|
||||
ret
|
||||
4: ld a,' '
|
||||
0: ld (de),a
|
||||
inc de
|
||||
djnz 0b
|
||||
pop iy
|
||||
ret
|
||||
|
||||
! various routines
|
||||
ux_close:
|
||||
pop hl
|
||||
ld a,l
|
||||
sub 3
|
||||
jp m,1f
|
||||
cp maxfiles
|
||||
call m,closefil
|
||||
1: ld hl,0
|
||||
push hl ; jr rtn
|
||||
|
||||
closefil:
|
||||
call findfile
|
||||
ld a,(ix+openflag)
|
||||
or a
|
||||
jr z,3f
|
||||
ld (ix+openflag),0
|
||||
cp 1
|
||||
jr z,2f
|
||||
ld a,(ix+nleft)
|
||||
cp 128
|
||||
jr z,2f
|
||||
call flsbuf
|
||||
2:
|
||||
push iy
|
||||
push ix
|
||||
pop de
|
||||
ld c,close
|
||||
call bdos
|
||||
pop iy
|
||||
3: ret
|
||||
|
||||
ux_ioctl:
|
||||
pop hl
|
||||
ld a,l
|
||||
sub 3
|
||||
jp p,1f
|
||||
pop hl
|
||||
ld a,h
|
||||
cp 't'
|
||||
jr nz,e.mon
|
||||
ld a,l
|
||||
cp 8
|
||||
jr z,tiocgetp
|
||||
cp 9
|
||||
jr z,tiocsetp
|
||||
jr e.mon
|
||||
1: pop hl
|
||||
pop hl
|
||||
ld hl,-1
|
||||
push hl ; jr rtn
|
||||
tiocgetp:
|
||||
pop de
|
||||
ld hl,ttymode
|
||||
2: push bc
|
||||
ld bc,6
|
||||
ldir
|
||||
ld h,b
|
||||
ld l,c
|
||||
pop bc
|
||||
push hl ; jr rtn
|
||||
tiocsetp:
|
||||
pop hl
|
||||
ld de,ttymode
|
||||
jr 2b
|
||||
|
||||
ux_time:
|
||||
call time4
|
||||
rtn: ld ix,(return) ; jp (ix)
|
||||
|
||||
ux_ftime:
|
||||
pop hl
|
||||
ld (retarea+6),hl
|
||||
call time4
|
||||
ld hl,(retarea+6)
|
||||
pop de
|
||||
ld (hl),e
|
||||
inc hl
|
||||
ld (hl),d
|
||||
inc hl
|
||||
pop de
|
||||
ld (hl),e
|
||||
inc hl
|
||||
ld (hl),d
|
||||
inc hl
|
||||
xor a
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
ld ix,(return) ; jp (ix)
|
||||
|
||||
time4:
|
||||
pop hl
|
||||
ld (retarea),iy
|
||||
ld (retarea+2),bc
|
||||
ld (retarea+4),hl
|
||||
ld hl,(timebuf+2)
|
||||
push hl
|
||||
ld hl,(timebuf)
|
||||
push hl
|
||||
ld hl,0
|
||||
push hl
|
||||
ld hl,50
|
||||
push hl
|
||||
call .dvu4
|
||||
ld iy,(retarea)
|
||||
ld bc,(retarea+2)
|
||||
ld hl,(retarea+4)
|
||||
jp (hl)
|
||||
ux_exit:
|
||||
call uxfinish
|
||||
ld c,reset
|
||||
call bdos
|
||||
! no return
|
||||
|
||||
ux_creat:
|
||||
call emptyfile
|
||||
jr c,openfailed
|
||||
pop hl
|
||||
call parsename
|
||||
pop hl ! file mode, not used under CP/M
|
||||
push iy
|
||||
push ix
|
||||
push ix
|
||||
pop de
|
||||
ld c,delete
|
||||
call bdos
|
||||
pop de
|
||||
ld c,makefile
|
||||
call bdos
|
||||
pop iy
|
||||
ld l,1
|
||||
jr afteropen
|
||||
ux_open:
|
||||
call emptyfile
|
||||
jr nc,1f
|
||||
openfailed:
|
||||
pop hl
|
||||
pop hl ! remove params
|
||||
ld hl,EMFILE
|
||||
push hl
|
||||
push hl ; jr rtn
|
||||
1:
|
||||
pop hl ! filename
|
||||
call parsename
|
||||
push iy
|
||||
ld c,open
|
||||
push ix
|
||||
pop de
|
||||
call bdos
|
||||
pop iy
|
||||
pop hl
|
||||
afteropen:
|
||||
inc a
|
||||
jr nz,1f
|
||||
ld hl,ENOENT
|
||||
push hl
|
||||
push hl ; jr rtn
|
||||
1:
|
||||
inc l
|
||||
ld (ix+openflag),l
|
||||
xor a
|
||||
ld (ix+nleft),a
|
||||
ld (ix+zcount),a
|
||||
ld (ix+zsave),26
|
||||
bit 1,l
|
||||
jr z,2f
|
||||
ld (ix+nleft),128
|
||||
2:
|
||||
ld (ix+position),a
|
||||
ld (ix+position+1),a
|
||||
push ix
|
||||
pop hl
|
||||
push bc
|
||||
ld b,128
|
||||
3: dec hl
|
||||
ld (hl),26
|
||||
djnz 3b
|
||||
pop bc
|
||||
ld (ix+iopointer+1),h
|
||||
ld (ix+iopointer),l
|
||||
ld h,a
|
||||
ld l,(ix+fildes)
|
||||
push hl
|
||||
ld l,a
|
||||
push hl ; jr rtn
|
||||
|
||||
ux_read:
|
||||
pop hl
|
||||
ld a,l
|
||||
sub 3
|
||||
jp p,readfile
|
||||
ld a,(ttymode+4)
|
||||
bit 5,a
|
||||
jr z,1f ! not raw
|
||||
push iy
|
||||
! #ifdef CPM1
|
||||
!raw echo interface
|
||||
ld c,consolein
|
||||
call bdos
|
||||
! #else
|
||||
! !no echo interface
|
||||
! 4:
|
||||
! ld c,diconio
|
||||
! ld e,0xff
|
||||
! call bdos
|
||||
! or a
|
||||
! jr z,4b
|
||||
!end of no echo interface
|
||||
! #endif
|
||||
pop iy
|
||||
pop hl
|
||||
ld (hl),a
|
||||
pop hl
|
||||
ld hl,1
|
||||
push hl
|
||||
ld hl,0
|
||||
push hl ; jr rtn
|
||||
1:
|
||||
ld hl,sibuf+1 ! read from console assumed
|
||||
dec (hl)
|
||||
jp p,2f
|
||||
dec hl ! go read console line
|
||||
ld (hl),80 ! max line length
|
||||
push iy
|
||||
push hl
|
||||
ld c,readconsole
|
||||
ex de,hl
|
||||
call bdos
|
||||
ld c,writeconsole
|
||||
ld e,'\n'
|
||||
call bdos
|
||||
pop hl
|
||||
pop iy
|
||||
inc hl
|
||||
inc (hl)
|
||||
ld (siptr),hl ! ready for transfer
|
||||
push hl
|
||||
ld e,(hl)
|
||||
ld d,0
|
||||
add hl,de
|
||||
ld (hl),'\r'
|
||||
inc hl
|
||||
ld (hl),'\n'
|
||||
pop hl
|
||||
2:
|
||||
push bc
|
||||
pop ix
|
||||
ld b,(hl)
|
||||
inc b ! bytes remaining
|
||||
pop hl ! copy to
|
||||
pop de ! bytes wanted (probably 512)
|
||||
push ix
|
||||
ld ix,(siptr) ! copy from
|
||||
xor a ! find out minimum of ramaining and wanted
|
||||
or d
|
||||
jr nz,3f ! more than 255 wanted (forget that)
|
||||
ld a,b
|
||||
cp e
|
||||
jp m,3f ! not enough remaining
|
||||
ld b,e
|
||||
3:
|
||||
ld c,b ! keep copy
|
||||
0:
|
||||
inc ix
|
||||
ld a,(ix)
|
||||
ld (hl),a
|
||||
inc hl
|
||||
djnz 0b
|
||||
ld a,(sibuf+1)
|
||||
sub c
|
||||
inc a
|
||||
ld (sibuf+1),a
|
||||
ld (siptr),ix
|
||||
pop hl
|
||||
push bc
|
||||
ld c,b
|
||||
push bc ! load 0
|
||||
ld b,h
|
||||
ld c,l
|
||||
ld ix,(return) ; jp (ix)
|
||||
readfile:
|
||||
call findfile
|
||||
pop de
|
||||
pop hl ! count
|
||||
push bc
|
||||
ld bc,0
|
||||
0:
|
||||
xor a
|
||||
or l
|
||||
jr z,1f
|
||||
dec l
|
||||
3:
|
||||
! warning: this may not work if zcount overflows
|
||||
ld a,(ix+zcount)
|
||||
or a
|
||||
jr nz,5f
|
||||
ld a,(ix+zsave)
|
||||
cp 26
|
||||
jr z,4f
|
||||
ld (ix+zsave),26
|
||||
jr 8f
|
||||
4:
|
||||
call getchar
|
||||
jr c,2f
|
||||
ld (de),a
|
||||
sub 26 ! CTRL-Z
|
||||
jr z,7f
|
||||
ld a,(ix+zcount)
|
||||
or a
|
||||
jr z,6f
|
||||
ld a,(de)
|
||||
ld (ix+zsave),a
|
||||
5:
|
||||
ld a,26
|
||||
dec (ix+zcount)
|
||||
8:
|
||||
ld (de),a
|
||||
6:
|
||||
inc de
|
||||
inc bc
|
||||
jr 0b
|
||||
1:
|
||||
dec l
|
||||
dec h
|
||||
jp p,3b
|
||||
2:
|
||||
pop hl
|
||||
push bc
|
||||
ld b,h
|
||||
ld c,l
|
||||
ld hl,0
|
||||
push hl ; jr rtn
|
||||
7:
|
||||
inc (ix+zcount)
|
||||
jr 4b
|
||||
|
||||
ux_write:
|
||||
pop hl
|
||||
ld a,l
|
||||
sub 3
|
||||
jp p,writefile
|
||||
pop hl ! buffer address
|
||||
pop de ! count
|
||||
push de
|
||||
ld ix,0
|
||||
push ix
|
||||
push bc
|
||||
ld b,e ! count now in 'db'
|
||||
0:
|
||||
ld a,b
|
||||
or a
|
||||
jr nz,1f
|
||||
ld a,d
|
||||
or a
|
||||
jr nz,2f
|
||||
pop bc
|
||||
ld ix,(return) ; jp (ix)
|
||||
2:
|
||||
dec d
|
||||
1:
|
||||
dec b
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
ld c,writeconsole
|
||||
call bdos
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
jr 0b
|
||||
writefile:
|
||||
call findfile
|
||||
pop de
|
||||
pop hl ! count
|
||||
push bc
|
||||
ld bc,0
|
||||
0:
|
||||
xor a
|
||||
or l
|
||||
jr z,1f
|
||||
dec l
|
||||
3:
|
||||
ld a,(de)
|
||||
inc de
|
||||
call putchar
|
||||
jr c,4f
|
||||
inc bc
|
||||
jr 0b
|
||||
1:
|
||||
dec l
|
||||
dec h
|
||||
jp p,3b
|
||||
ld ix,0
|
||||
2:
|
||||
pop hl
|
||||
push bc
|
||||
ld b,h
|
||||
ld c,l
|
||||
push ix
|
||||
ld ix,(return) ; jp (ix)
|
||||
4:
|
||||
ld ix,ENOSPC
|
||||
jr 2b
|
||||
|
||||
ux_unlink:
|
||||
pop hl
|
||||
ld ix,fcb
|
||||
call parsename
|
||||
push bc
|
||||
ld c,delete
|
||||
ld de,fcb
|
||||
call bdos
|
||||
pop bc
|
||||
inc a
|
||||
jr nz,1f
|
||||
ld hl,ENOENT
|
||||
push hl ; jr rtn
|
||||
1:
|
||||
ld hl,0
|
||||
push hl ; jr rtn
|
||||
|
||||
ux_getpid:
|
||||
ld hl,12345 ! nice number
|
||||
push hl ; jr rtn
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
retarea: .word 0 ! base of buffer for result values (max 8 bytes)
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
trapproc:
|
||||
.word 0
|
||||
|
||||
nextp: .byte 0
|
||||
|
||||
header:
|
||||
ntext: .word 0
|
||||
ndata: .word 0
|
||||
nproc: .word 0
|
||||
entry: .word 0
|
||||
nline: .word 0
|
||||
|
||||
hp: .word 0
|
||||
pb: .word 0
|
||||
pd: .word 0
|
102
mach/z80/libsys/mon.s
Normal file
102
mach/z80/libsys/mon.s
Normal file
|
@ -0,0 +1,102 @@
|
|||
.define .mon
|
||||
|
||||
! Monitor call
|
||||
! Expects on stack: monitor call number
|
||||
! parameters
|
||||
! Implemented are the following monitor calls:
|
||||
! number 1: exit
|
||||
! number 3: read
|
||||
! number 4: write
|
||||
! number 5: open
|
||||
! number 6: close
|
||||
! number 54: ioctl
|
||||
! If called with a number of a call that is not implemented,
|
||||
! a trap is generated.
|
||||
|
||||
.mon:
|
||||
pop ix ! returnaddress
|
||||
|
||||
pop hl ! monitor call number
|
||||
ld a,l
|
||||
cp 1
|
||||
jp z,monexit ! is it an exit?
|
||||
cp 3
|
||||
jp z,monread ! is it a read?
|
||||
cp 4
|
||||
jp z,monwrite ! is it a write?
|
||||
cp 5
|
||||
jp z,monopen ! is it an open?
|
||||
cp 6
|
||||
jp z,monclose ! is it a close?
|
||||
cp 54
|
||||
jp z,monioctl
|
||||
jp ebadmon ! trap
|
||||
|
||||
monexit:
|
||||
jp 0x38
|
||||
|
||||
monread:
|
||||
pop hl ! file-descriptor, not used
|
||||
pop hl ! hl = pointer to output buffer
|
||||
pop de ! de = number of bytes to be read
|
||||
ld bc,0 ! bc will contain the number of bytes actually read
|
||||
1: ld a,d
|
||||
or e
|
||||
jr z,2f
|
||||
call getchar
|
||||
push af
|
||||
call putchar ! echo character
|
||||
pop af
|
||||
ld (hl),a
|
||||
inc hl
|
||||
inc bc
|
||||
dec de
|
||||
cp 0x0A ! is it a newline?
|
||||
jp nz,1b
|
||||
2: push bc
|
||||
ld hl,0
|
||||
push hl
|
||||
jp (ix)
|
||||
|
||||
monwrite:
|
||||
pop hl ! file-descriptor, not used
|
||||
pop hl ! hl = pointer to output buffer
|
||||
pop de ! de = number of bytes
|
||||
push de
|
||||
1: ld a,e
|
||||
or d
|
||||
jr z,2f
|
||||
ld a,(hl)
|
||||
call putchar
|
||||
inc hl
|
||||
dec de
|
||||
jp 1b
|
||||
|
||||
2: push de ! no error
|
||||
jp (ix)
|
||||
|
||||
|
||||
monopen:
|
||||
pop hl ! pointer to string
|
||||
pop hl ! flag
|
||||
ld hl,-1
|
||||
push hl ! push file descriptor
|
||||
push hl ! push error code twice
|
||||
push hl
|
||||
jp (ix)
|
||||
|
||||
monclose:
|
||||
ex (sp),hl ! pop file descriptor and push error code
|
||||
pop hl ! file descriptor
|
||||
ld hl,-1
|
||||
push hl ! push error code twice
|
||||
push hl
|
||||
jp (ix)
|
||||
|
||||
monioctl:
|
||||
pop hl ! file descriptor
|
||||
pop hl ! request
|
||||
ld hl,0
|
||||
ex (sp),hl ! remove argp and push error code
|
||||
jp (ix)
|
||||
|
28
mach/z80/libsys/putchr.nas.s
Normal file
28
mach/z80/libsys/putchr.nas.s
Normal file
|
@ -0,0 +1,28 @@
|
|||
.define putchr
|
||||
! output routine in monitor
|
||||
CRT = 0x013B
|
||||
! output a charcter
|
||||
! entry: ascii character in a
|
||||
putchr:
|
||||
push hl
|
||||
push bc
|
||||
ld hl,tab
|
||||
ld b,5
|
||||
1: cp (hl)
|
||||
jr z,fetch
|
||||
inc hl
|
||||
inc hl
|
||||
djnz 1b
|
||||
2: call CRT
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
fetch: inc hl
|
||||
ld a,(hl)
|
||||
jr 2b
|
||||
! conversion table for nascom characters
|
||||
tab: .byte 0x0D,0x00
|
||||
.byte 0x1B,0x1E
|
||||
.byte 0x08,0x1D
|
||||
.byte 0x0A,0x1F
|
||||
.byte 0x7F,0x00
|
21
mach/z80/libsys/putchr.s
Normal file
21
mach/z80/libsys/putchr.s
Normal file
|
@ -0,0 +1,21 @@
|
|||
.define putchr
|
||||
|
||||
putchr:
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
cp 0x0A
|
||||
jr nz,1f
|
||||
ld a,0x1F
|
||||
1:
|
||||
ld c,a
|
||||
2:
|
||||
in a,0xF1
|
||||
and 4
|
||||
jr z,2b
|
||||
ld a,c
|
||||
out 0xF0,a
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
197
mach/z80/libsys/subr.s
Normal file
197
mach/z80/libsys/subr.s
Normal file
|
@ -0,0 +1,197 @@
|
|||
.define _read,_write,_ioctl,_getpid,_open,_close,_exit,_errno
|
||||
_read:
|
||||
ld (savebc),bc
|
||||
push af
|
||||
pop bc
|
||||
ld (saveaf),bc ! save all registers in savereg
|
||||
ld (savede),de
|
||||
ld (savehl),hl
|
||||
ld (saveix),ix
|
||||
ex (sp),hl ! return address in hl
|
||||
pop bc ! skip return address
|
||||
pop bc ! get fd
|
||||
ld a,b ! check fd = 0
|
||||
or c
|
||||
jr nz,errrd
|
||||
pop de ! get buffer
|
||||
pop bc ! get count
|
||||
ld ix,0 ! reset counter
|
||||
push bc
|
||||
push de
|
||||
push ix
|
||||
push hl ! return address
|
||||
ex de,hl ! buffer to hl
|
||||
1: ld a,b
|
||||
or c
|
||||
jr z,done ! done if count = 0
|
||||
call getchr
|
||||
ld (hl),a
|
||||
inc hl ! increment pointer
|
||||
inc ix ! increment char counter
|
||||
dec bc ! decrement count
|
||||
cp 0xA
|
||||
jr nz,1b ! done if char = CR
|
||||
done:
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
ret
|
||||
errrd:
|
||||
push bc
|
||||
push hl ! return address
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
ld ix,-1
|
||||
ret
|
||||
|
||||
_write:
|
||||
ld (savebc),bc
|
||||
push af
|
||||
pop bc
|
||||
ld (saveaf),bc ! save all registers in savereg
|
||||
ld (savede),de
|
||||
ld (savehl),hl
|
||||
ld (saveix),ix
|
||||
ex (sp),hl ! return address in hl
|
||||
pop de ! skip return address
|
||||
pop de ! get fd
|
||||
ld a,e ! check for fd = 1
|
||||
cp 1
|
||||
jr nz,errwr
|
||||
ld a,d
|
||||
or a
|
||||
jr nz,errwr
|
||||
pop de ! buffer in de
|
||||
pop bc ! count in bc
|
||||
push bc
|
||||
push de
|
||||
push de
|
||||
push hl
|
||||
ex de,hl ! buffer in hl
|
||||
ld e,c
|
||||
ld d,b ! count also in de
|
||||
1: ld a,b
|
||||
or c
|
||||
jr z,exit
|
||||
ld a,(hl)
|
||||
call putchr
|
||||
inc hl
|
||||
dec bc
|
||||
jr 1b
|
||||
errwr:
|
||||
push de
|
||||
push hl
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
ld ix,-1 ! error in fd
|
||||
ret
|
||||
exit:
|
||||
push de ! count on stack
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
pop ix ! return count to caller
|
||||
ret
|
||||
|
||||
_ioctl:
|
||||
ret
|
||||
_getpid:
|
||||
ret
|
||||
|
||||
! open return a file descriptor (0,1,2)
|
||||
! depending on 'mode'
|
||||
! mode 2 doesn't work!!
|
||||
_open:
|
||||
ld (savebc),bc
|
||||
push af
|
||||
pop bc
|
||||
ld (saveaf),bc ! save all registers in savereg
|
||||
ld (savede),de
|
||||
ld (savehl),hl
|
||||
ld (saveix),ix
|
||||
pop bc ! return address
|
||||
pop de ! name pointer
|
||||
pop ix ! mode (0 for read,
|
||||
! 1 for write)
|
||||
push ix
|
||||
push de
|
||||
push bc
|
||||
ld bc,(saveaf)
|
||||
push bc
|
||||
pop af
|
||||
ld bc,(savebc)
|
||||
ld de,(savede)
|
||||
ld hl,(savehl)
|
||||
ld ix,(saveix)
|
||||
ret ! return fd = 0 for read
|
||||
! fd = 1 for write
|
||||
|
||||
_close:
|
||||
ld ix,0 ! return succes
|
||||
ret
|
||||
_exit:
|
||||
jp 0x38
|
||||
.data
|
||||
_errno:
|
||||
.word 0
|
||||
! output routine in monitor
|
||||
CRT = 0x013B
|
||||
! output a charcter
|
||||
! entry: ascii character in a
|
||||
.text
|
||||
!putchr:
|
||||
! push hl
|
||||
! push bc
|
||||
! ld hl,tab
|
||||
! ld b,5
|
||||
!1: cp (hl)
|
||||
! jr z,fetch
|
||||
! inc hl
|
||||
! inc hl
|
||||
! djnz 1b
|
||||
!2: call CRT
|
||||
! pop bc
|
||||
! pop hl
|
||||
! ret
|
||||
!fetch: inc hl
|
||||
! ld a,(hl)
|
||||
! jr 2b
|
||||
!! conversion table for nascom characters
|
||||
!tab: .byte 0x0D,0x00
|
||||
! .byte 0x1B,0x1E
|
||||
! .byte 0x08,0x1D
|
||||
! .byte 0x0A,0x1F
|
||||
! .byte 0x7F,0x00
|
||||
|
||||
KBD = 0x69
|
||||
! get character from keyboard
|
||||
getchr:
|
||||
call KBD
|
||||
jr nc,getchr
|
||||
cp 0x1F
|
||||
jr z,CR
|
||||
cp 0x1D
|
||||
jr z,BS
|
||||
ret
|
||||
CR: ld a,0xA
|
||||
ret
|
||||
BS: ld a,0x8
|
||||
ret
|
Loading…
Reference in a new issue