*** empty log message ***
authorkeie <none@none>
Mon, 1 Apr 1985 14:44:26 +0000 (14:44 +0000)
committerkeie <none@none>
Mon, 1 Apr 1985 14:44:26 +0000 (14:44 +0000)
18 files changed:
mach/z80/libmon/Makefile [new file with mode: 0644]
mach/z80/libmon/README [new file with mode: 0644]
mach/z80/libmon/char.her.s [new file with mode: 0644]
mach/z80/libmon/head_em.s [new file with mode: 0644]
mach/z80/libmon/mon.cpm.s [new file with mode: 0644]
mach/z80/libmon/mon.s [new file with mode: 0644]
mach/z80/libmon/putchr.nas.s [new file with mode: 0644]
mach/z80/libmon/putchr.s [new file with mode: 0644]
mach/z80/libmon/subr.s [new file with mode: 0644]
mach/z80/libsys/Makefile [new file with mode: 0644]
mach/z80/libsys/README [new file with mode: 0644]
mach/z80/libsys/char.her.s [new file with mode: 0644]
mach/z80/libsys/head_em.s [new file with mode: 0644]
mach/z80/libsys/mon.cpm.s [new file with mode: 0644]
mach/z80/libsys/mon.s [new file with mode: 0644]
mach/z80/libsys/putchr.nas.s [new file with mode: 0644]
mach/z80/libsys/putchr.s [new file with mode: 0644]
mach/z80/libsys/subr.s [new file with mode: 0644]

diff --git a/mach/z80/libmon/Makefile b/mach/z80/libmon/Makefile
new file mode 100644 (file)
index 0000000..c6dfd6f
--- /dev/null
@@ -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
diff --git a/mach/z80/libmon/README b/mach/z80/libmon/README
new file mode 100644 (file)
index 0000000..55e9255
--- /dev/null
@@ -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.
diff --git a/mach/z80/libmon/char.her.s b/mach/z80/libmon/char.her.s
new file mode 100644 (file)
index 0000000..8ee338a
--- /dev/null
@@ -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
diff --git a/mach/z80/libmon/head_em.s b/mach/z80/libmon/head_em.s
new file mode 100644 (file)
index 0000000..1f91d0e
--- /dev/null
@@ -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
diff --git a/mach/z80/libmon/mon.cpm.s b/mach/z80/libmon/mon.cpm.s
new file mode 100644 (file)
index 0000000..79fd467
--- /dev/null
@@ -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
diff --git a/mach/z80/libmon/mon.s b/mach/z80/libmon/mon.s
new file mode 100644 (file)
index 0000000..0e997f1
--- /dev/null
@@ -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)
+
diff --git a/mach/z80/libmon/putchr.nas.s b/mach/z80/libmon/putchr.nas.s
new file mode 100644 (file)
index 0000000..e0dbdeb
--- /dev/null
@@ -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
diff --git a/mach/z80/libmon/putchr.s b/mach/z80/libmon/putchr.s
new file mode 100644 (file)
index 0000000..db15bf2
--- /dev/null
@@ -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
diff --git a/mach/z80/libmon/subr.s b/mach/z80/libmon/subr.s
new file mode 100644 (file)
index 0000000..2530488
--- /dev/null
@@ -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
diff --git a/mach/z80/libsys/Makefile b/mach/z80/libsys/Makefile
new file mode 100644 (file)
index 0000000..c6dfd6f
--- /dev/null
@@ -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
diff --git a/mach/z80/libsys/README b/mach/z80/libsys/README
new file mode 100644 (file)
index 0000000..55e9255
--- /dev/null
@@ -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.
diff --git a/mach/z80/libsys/char.her.s b/mach/z80/libsys/char.her.s
new file mode 100644 (file)
index 0000000..8ee338a
--- /dev/null
@@ -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
diff --git a/mach/z80/libsys/head_em.s b/mach/z80/libsys/head_em.s
new file mode 100644 (file)
index 0000000..1f91d0e
--- /dev/null
@@ -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
diff --git a/mach/z80/libsys/mon.cpm.s b/mach/z80/libsys/mon.cpm.s
new file mode 100644 (file)
index 0000000..79fd467
--- /dev/null
@@ -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
diff --git a/mach/z80/libsys/mon.s b/mach/z80/libsys/mon.s
new file mode 100644 (file)
index 0000000..0e997f1
--- /dev/null
@@ -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)
+
diff --git a/mach/z80/libsys/putchr.nas.s b/mach/z80/libsys/putchr.nas.s
new file mode 100644 (file)
index 0000000..e0dbdeb
--- /dev/null
@@ -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
diff --git a/mach/z80/libsys/putchr.s b/mach/z80/libsys/putchr.s
new file mode 100644 (file)
index 0000000..db15bf2
--- /dev/null
@@ -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
diff --git a/mach/z80/libsys/subr.s b/mach/z80/libsys/subr.s
new file mode 100644 (file)
index 0000000..2530488
--- /dev/null
@@ -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