123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929 |
- .define .mon
- .define uxfinish
- .sect .text
- .sect .rom
- .sect .data
- .sect .bss
- .sect .text
- ! 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
- .assert [ filefcb] <> 0
- 0: .space maxfiles*filesize
- filearea = 0b+128
- sibuf:
- .data2 0
- .space 82
- siptr: .space 2
- saveargs:
- .space 128
- argc: .space 2
- ttymode:.data1 9,9,8,21;.data2 06310+RAW*040 ! raw = 040
- return:
- .data2 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:
- .data2 e.mon ! ux_indir
- .data2 ux_exit
- .data2 e.mon ! ux_fork
- .data2 ux_read
- .data2 ux_write
- .data2 ux_open
- .data2 ux_close
- .data2 e.mon ! ux_wait
- .data2 ux_creat
- .data2 e.mon ! ux_link
- .data2 ux_unlink
- .data2 e.mon ! ux_exec
- .data2 e.mon ! ux_chdir
- .data2 ux_time
- .data2 e.mon ! ux_mknod
- .data2 e.mon ! ux_chmod
- .data2 e.mon ! ux_chown
- .data2 e.mon ! ux_break
- .data2 e.mon ! ux_stat
- .data2 e.mon ! ux_seek
- .data2 ux_getpid
- .data2 e.mon ! ux_mount
- .data2 e.mon ! ux_umount
- .data2 e.mon ! ux_setuid
- .data2 e.mon ! ux_getuid
- .data2 e.mon ! ux_stime
- .data2 e.mon ! ux_ptrace
- .data2 e.mon ! ux_alarm
- .data2 e.mon ! ux_fstat
- .data2 e.mon ! ux_pause
- .data2 e.mon ! ux_utime
- .data2 e.mon ! ux_stty
- .data2 e.mon ! ux_gtty
- .data2 e.mon ! ux_access
- .data2 e.mon ! ux_nice
- .data2 ux_ftime
- .data2 e.mon ! ux_sync
- .data2 e.mon ! ux_kill
- .data2 unimpld
- .data2 unimpld
- .data2 unimpld
- .data2 e.mon ! ux_dup
- .data2 e.mon ! ux_pipe
- .data2 e.mon ! ux_times
- .data2 e.mon ! ux_prof
- .data2 e.mon ! ux_unused
- .data2 e.mon ! ux_setgid
- .data2 e.mon ! ux_getgid
- .data2 e.mon ! ux_sig
- .data2 unimpld
- .data2 unimpld
- .data2 unimpld
- .data2 unimpld
- .data2 unimpld
- .data2 ux_ioctl
- .data2 unimpld
- .data2 unimpld
- .data2 unimpld
- .data2 unimpld
- .data2 unimpld ! ux_exece
- .data2 e.mon ! ux_umask
- .data2 e.mon ! ux_chroot
- .data2 unimpld
- .data2 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: .data2 0 ! base of buffer for result values (max 8 bytes)
- .data2 0
- .data2 0
- .data2 0
- trapproc:
- .data2 0
- nextp: .data1 0
- header:
- ntext: .data2 0
- ndata: .data2 0
- nproc: .data2 0
- entry: .data2 0
- nline: .data2 0
- hp: .data2 0
- pb: .data2 0
- pd: .data2 0
|