Pristine Ack-5.5
[Ack-5.5.git] / mach / z80 / libmon / mon.cpm.s
1 .define .mon
2 .define uxfinish
3 .sect .text
4 .sect .rom
5 .sect .data
6 .sect .bss
7 .sect .text
8
9 ! monitor instruction
10 ! a small collection of UNIX system calls implemented under CP/M
11
12 !       ux_indir=e.mon
13 !       ux_fork=e.mon
14 !       ux_wait=e.mon
15 !       ux_link=e.mon
16 !       ux_exec=e.mon
17 !       ux_chdir=e.mon
18 !       ux_mknod=e.mon
19 !       ux_chmod=e.mon
20 !       ux_chown=e.mon
21 !       ux_break=e.mon
22 !       ux_stat=e.mon
23 !       ux_seek=e.mon
24 !       ux_mount=e.mon
25 !       ux_umount=e.mon
26 !       ux_setuid=e.mon
27 !       ux_getuid=e.mon
28 !       ux_stime=e.mon
29 !       ux_ptrace=e.mon
30 !       ux_alarm=e.mon
31 !       ux_fstat=e.mon
32 !       ux_pause=e.mon
33 !       ux_utime=e.mon
34 !       ux_stty=e.mon
35 !       ux_gtty=e.mon
36 !       ux_access=e.mon
37 !       ux_nice=e.mon
38 !       ux_sync=e.mon
39 !       ux_kill=e.mon
40 !       ux_dup=e.mon
41 !       ux_pipe=e.mon
42 !       ux_times=e.mon
43 !       ux_prof=e.mon
44 !       ux_unused=e.mon
45 !       ux_setgid=e.mon
46 !       ux_getgid=e.mon
47 !       ux_sig=e.mon
48 !       ux_umask=e.mon
49 !       ux_chroot=e.mon
50
51         EPERM   = 1
52         ENOENT  = 2
53         ESRCH   = 3
54         EINTR   = 4
55         EIO     = 5
56         ENXIO   = 6
57         E2BIG   = 7
58         ENOEXEC = 8
59         EBADF   = 9
60         ECHILD  = 10
61         EAGAIN  = 11
62         ENOMEM  = 12
63         EACCES  = 13
64         EFAULT  = 14
65         ENOTBLK = 15
66         EBUSY   = 16
67         EEXIST  = 17
68         EXDEV   = 18
69         ENODEV  = 19
70         ENOTDIR = 20
71         EISDIR  = 21
72         EINVAL  = 22
73         ENFILE  = 23
74         EMFILE  = 24
75         ENOTTY  = 25
76         ETXTBSY = 26
77         EFBIG   = 27
78         ENOSPC  = 28
79         ESPIPE  = 29
80         EROFS   = 30
81         EMLINK  = 31
82         EPIPE   = 32
83         EDOM    = 33
84 ! Structure of filearea maintained by this implementation
85 ! First iobuffer of 128 bytes
86 ! Then the fcb area of 36 bytes
87 ! The number of bytes left in the buffer, 1 byte
88 ! The iopointer into the buffer, 2 bytes
89 ! The openflag 0 unused, 1 reading, 2 writing, 1 byte
90 ! The filedescriptor starting at 3, 1 byte
91 ! The number of CTRL-Zs that have been absorbed, 1 byte
92 ! The byte read after a sequence of CTRL-Zs, 1 byte
93
94         maxfiles=8
95         filesize=128+36+1+2+1+1+1+1
96
97         filefcb=0       ! pointers point to fcb
98         position=33
99         nleft=36
100         iopointer=37
101         openflag=39
102         fildes=40
103         zcount=41
104         zsave=42
105
106         .assert [ filefcb] <> 0
107
108 0:      .space maxfiles*filesize
109         filearea = 0b+128
110 sibuf:
111         .data2 0
112         .space 82
113 siptr:  .space 2
114 saveargs:
115         .space 128
116 argc:   .space 2
117 ttymode:.data1 9,9,8,21;.data2 06310+RAW*040    ! raw = 040
118
119 return:
120         .data2 0,0
121 uxinit:
122         xor a
123         ld c,maxfiles
124         ld hl,0b
125 1:      ld b,filesize
126 2:      ld (hl),a
127         inc hl
128         djnz 2b
129         dec c
130         jr nz,1b
131         ret
132
133 uxfinish:
134         ld a,maxfiles-1
135 1:      push af
136         call closefil
137         pop af
138         dec a
139         cp 0377
140         jr nz,1b
141         ret
142
143 .mon:
144         pop ix
145         ld (return),ix  ! return adres
146         pop de          ! system call number
147         xor a
148         or d
149         jr nz,unimpld   ! too big
150         ld a,e
151         and 0300        ! only 64 system calls
152         jr nz,unimpld
153         sla e
154         ld hl,systab
155         add hl,de
156         ld e,(hl)
157         inc hl
158         ld d,(hl)
159         ex de,hl
160         jp (hl)
161
162 systab: 
163         .data2 e.mon    ! ux_indir
164         .data2 ux_exit
165         .data2 e.mon    ! ux_fork
166         .data2 ux_read
167         .data2 ux_write
168         .data2 ux_open
169         .data2 ux_close
170         .data2 e.mon    ! ux_wait
171         .data2 ux_creat
172         .data2 e.mon    ! ux_link
173         .data2 ux_unlink
174         .data2 e.mon    ! ux_exec
175         .data2 e.mon    ! ux_chdir
176         .data2 ux_time
177         .data2 e.mon    ! ux_mknod
178         .data2 e.mon    ! ux_chmod
179         .data2 e.mon    ! ux_chown
180         .data2 e.mon    ! ux_break
181         .data2 e.mon    ! ux_stat
182         .data2 e.mon    ! ux_seek
183         .data2 ux_getpid
184         .data2 e.mon    ! ux_mount
185         .data2 e.mon    ! ux_umount
186         .data2 e.mon    ! ux_setuid
187         .data2 e.mon    ! ux_getuid
188         .data2 e.mon    ! ux_stime
189         .data2 e.mon    ! ux_ptrace
190         .data2 e.mon    ! ux_alarm
191         .data2 e.mon    ! ux_fstat
192         .data2 e.mon    ! ux_pause
193         .data2 e.mon    ! ux_utime
194         .data2 e.mon    ! ux_stty
195         .data2 e.mon    ! ux_gtty
196         .data2 e.mon    ! ux_access
197         .data2 e.mon    ! ux_nice
198         .data2 ux_ftime
199         .data2 e.mon    ! ux_sync
200         .data2 e.mon    ! ux_kill
201         .data2 unimpld
202         .data2 unimpld
203         .data2 unimpld
204         .data2 e.mon    ! ux_dup
205         .data2 e.mon    ! ux_pipe
206         .data2 e.mon    ! ux_times
207         .data2 e.mon    ! ux_prof
208         .data2 e.mon    ! ux_unused
209         .data2 e.mon    ! ux_setgid
210         .data2 e.mon    ! ux_getgid
211         .data2 e.mon    ! ux_sig
212         .data2 unimpld
213         .data2 unimpld
214         .data2 unimpld
215         .data2 unimpld
216         .data2 unimpld
217         .data2 ux_ioctl
218         .data2 unimpld
219         .data2 unimpld
220         .data2 unimpld
221         .data2 unimpld
222         .data2 unimpld  ! ux_exece
223         .data2 e.mon    ! ux_umask
224         .data2 e.mon    ! ux_chroot
225         .data2 unimpld
226         .data2 unimpld
227
228 emptyfile:
229         ! searches for a free filestructure
230         ! returns pointer in iy, 0 if not found
231         ld ix,filearea
232         ld l,maxfiles
233 1:
234         xor a
235         or (ix+openflag)
236         jr nz,3f
237         ld a,maxfiles+3
238         sub l
239         ld (ix+fildes),a
240 ! #ifdef        CPM1
241         push iy
242         push ix
243         ld de,-128
244         add ix,de
245         push ix
246         pop de
247         ld c,setdma
248         call bdos
249         pop ix
250         pop iy
251         or a            ! to clear C
252 ! #endif
253         ret
254 3:
255         ld de,filesize
256         add ix,de
257         dec l
258         jr nz,1b
259         scf
260         ret
261
262 findfile:
263         ld ix,filearea
264         ld de,filesize
265 0:
266         dec a
267         ret m
268         add ix,de
269         jr 0b
270
271 getchar:
272         push iy
273         push de
274         push hl
275         dec (ix+nleft)
276         jp p,0f
277         push ix
278         pop hl
279         ld de,-128
280         add hl,de
281         ld (ix+iopointer),l
282         ld (ix+iopointer+1),h
283         ex de,hl
284         push ix
285         ld c,setdma
286         call bdos
287 ! #ifdef        CPM1
288         ld c,seqread
289 ! #else
290 !       ld c,randomread
291 ! #endif
292         pop de
293         call bdos
294         or a
295         jr z,1f
296         ld (ix+zcount),0
297         pop hl
298         pop de
299         pop iy
300         scf
301         ret
302 1:
303         inc (ix+position)
304         jr nz,2f
305         inc (ix+position+1)
306 2:
307         ld a,127
308         ld (ix+nleft),a
309 0:
310         ld h,(ix+iopointer+1)
311         ld l,(ix+iopointer)
312         ld a,(hl)
313         inc hl
314         ld (ix+iopointer),l
315         ld (ix+iopointer+1),h
316         pop hl
317         pop de
318         pop iy
319         ret
320         or a
321
322 putchar:
323         push hl
324         ld h,(ix+iopointer+1)
325         ld l,(ix+iopointer)
326         ld (hl),a
327         dec (ix+nleft)
328         jr z,0f
329         inc hl
330         ld (ix+iopointer+1),h
331         ld (ix+iopointer),l
332         pop hl
333         ret
334 0:
335         pop hl
336 flsbuf:
337         push hl
338         push de
339         push iy
340         push ix
341         pop hl
342         ld de,-128
343         add hl,de
344         ld (ix+iopointer+1),h
345         ld (ix+iopointer),l
346         ex de,hl
347         push ix
348         ld c,setdma
349         call bdos
350         pop de
351 ! #ifdef        CPM1
352         ld c,seqwrite
353 ! #else
354 !       ld c,randomwrite
355 ! #endif
356         call bdos
357         or a
358         jr z,1f
359         pop iy
360         pop de
361         pop hl
362         scf
363         ret
364 1:
365         inc (ix+position)
366         jr nz,2f
367         inc (ix+position+1)
368 2:
369         ld a,128
370         ld (ix+nleft),a
371         ld b,a
372         push ix
373         pop hl
374         ld de,-128
375         add hl,de
376         ld a,26                 ! ctrl z
377 1:      ld (hl),a
378         inc hl
379         djnz 1b
380         pop iy
381         pop de
382         pop hl
383         or a
384         ret
385
386 parsename:
387         ! parses file name pointed to by hl and fills in fcb
388         ! of the file pointed to by ix.
389         ! recognizes filenames as complicated as 'b:file.zot'
390         ! and as simple as 'x'
391
392         push iy
393         push ix
394         pop de
395         xor a
396         push de
397         ld b,36         ! sizeof fcb
398 0:      ld (de),a
399         inc de
400         djnz 0b
401         pop de
402         inc hl
403         ld a,(hl)
404         dec hl
405         cp ':'          ! drive specified ?
406         jr nz,1f
407         ld a,(hl)
408         inc hl
409         inc hl
410         dec a
411         and 15
412         inc a           ! now 1<= a <= 16
413         ld (de),a
414 1:      inc de
415         ld b,8          ! filename maximum of 8 characters
416 1:      ld a,(hl)
417         or a
418         jr nz,8f
419         dec hl
420         ld a,'.'
421 8:
422         inc hl
423         cp '.'
424         jr z,2f
425         and 0177        ! no parity
426         bit 6,a
427         jr z,9f
428         and 0337        ! UPPER case
429 9:
430         ld (de),a
431         inc de
432         djnz 1b
433         ld a,(hl)
434         inc hl
435         cp '.'
436         jr z,3f
437         ld a,' '
438         ld (de),a
439         inc de
440         ld (de),a
441         inc de
442         ld (de),a
443         pop iy
444         ret             ! filenames longer than 8 are truncated
445 2:      ld a,' '        ! fill with spaces
446 0:      ld (de),a
447         inc de
448         djnz 0b
449 3:      ld b,3          ! length of extension
450 1:      ld a,(hl)
451         inc hl
452         or a
453         jr z,4f
454         cp 0100
455         jp m,2f
456         and 0137
457 2:      ld (de),a
458         inc de
459         djnz 1b
460         pop iy
461         ret
462 4:      ld a,' '
463 0:      ld (de),a
464         inc de
465         djnz 0b
466         pop iy
467         ret
468
469 ! various routines
470 ux_close:
471         pop hl
472         ld a,l
473         sub 3
474         jp m,1f
475         cp maxfiles
476         call m,closefil
477 1:      ld hl,0
478         push hl ; jr rtn
479
480 closefil:
481         call findfile
482         ld a,(ix+openflag)
483         or a
484         jr z,3f
485         ld (ix+openflag),0
486         cp 1
487         jr z,2f
488         ld a,(ix+nleft)
489         cp 128
490         jr z,2f
491         call flsbuf
492 2:
493         push iy
494         push ix
495         pop de
496         ld c,close
497         call bdos
498         pop iy
499 3:      ret
500
501 ux_ioctl:
502         pop hl
503         ld a,l
504         sub 3
505         jp p,1f
506         pop hl
507         ld a,h
508         cp 't'
509         jr nz,e.mon
510         ld a,l
511         cp 8
512         jr z,tiocgetp
513         cp 9
514         jr z,tiocsetp
515         jr e.mon
516 1:      pop hl
517         pop hl
518         ld hl,-1
519         push hl ; jr rtn
520 tiocgetp:
521         pop de
522         ld hl,ttymode
523 2:      push bc
524         ld bc,6
525         ldir
526         ld h,b
527         ld l,c
528         pop bc
529         push hl ; jr rtn
530 tiocsetp:
531         pop hl
532         ld de,ttymode
533         jr 2b
534
535 ux_time:
536         call time4
537 rtn:    ld ix,(return) ; jp (ix)
538
539 ux_ftime:
540         pop hl
541         ld (retarea+6),hl
542         call time4
543         ld hl,(retarea+6)
544         pop de
545         ld (hl),e
546         inc hl
547         ld (hl),d
548         inc hl
549         pop de
550         ld (hl),e
551         inc hl
552         ld (hl),d
553         inc hl
554         xor a
555         ld (hl),a
556         inc hl
557         ld (hl),a
558         inc hl
559         ld (hl),a
560         inc hl
561         ld (hl),a
562         inc hl
563         ld (hl),a
564         inc hl
565         ld (hl),a
566         ld ix,(return) ; jp (ix)
567
568 time4:
569         pop hl
570         ld (retarea),iy
571         ld (retarea+2),bc
572         ld (retarea+4),hl
573         ld hl,(timebuf+2)
574         push hl
575         ld hl,(timebuf)
576         push hl
577         ld hl,0
578         push hl
579         ld hl,50
580         push hl
581         call .dvu4
582         ld iy,(retarea)
583         ld bc,(retarea+2)
584         ld hl,(retarea+4)
585         jp (hl)
586 ux_exit:
587         call uxfinish
588         ld c,reset
589         call bdos
590         ! no return
591
592 ux_creat:
593         call emptyfile
594         jr c,openfailed
595         pop hl
596         call parsename
597         pop hl                  ! file mode, not used under CP/M
598         push iy
599         push ix
600         push ix
601         pop de
602         ld c,delete
603         call bdos
604         pop de
605         ld c,makefile
606         call bdos
607         pop iy
608         ld l,1
609         jr afteropen
610 ux_open:
611         call emptyfile
612         jr nc,1f
613 openfailed:
614         pop hl
615         pop hl          ! remove params
616         ld hl,EMFILE
617         push hl
618         push hl ; jr rtn
619 1:
620         pop hl          ! filename
621         call parsename
622         push iy
623         ld c,open
624         push ix
625         pop de
626         call bdos
627         pop iy
628         pop hl
629 afteropen:
630         inc a
631         jr nz,1f
632         ld hl,ENOENT
633         push hl
634         push hl ; jr rtn
635 1:
636         inc l
637         ld (ix+openflag),l
638         xor a
639         ld (ix+nleft),a
640         ld (ix+zcount),a
641         ld (ix+zsave),26
642         bit 1,l
643         jr z,2f
644         ld (ix+nleft),128
645 2:
646         ld (ix+position),a
647         ld (ix+position+1),a
648         push ix
649         pop hl
650         push bc
651         ld b,128
652 3:      dec hl
653         ld (hl),26
654         djnz 3b
655         pop bc
656         ld (ix+iopointer+1),h
657         ld (ix+iopointer),l
658         ld h,a
659         ld l,(ix+fildes)
660         push hl
661         ld l,a
662         push hl ; jr rtn
663
664 ux_read:
665         pop hl
666         ld a,l
667         sub 3
668         jp p,readfile
669         ld a,(ttymode+4)
670         bit 5,a
671         jr z,1f                 ! not raw
672         push iy
673 ! #ifdef        CPM1
674 !raw echo interface
675         ld c,consolein
676         call bdos
677 ! #else
678 ! !no echo interface
679 ! 4:
680 !       ld c,diconio
681 !       ld e,0xff
682 !       call bdos
683 !       or a
684 !       jr z,4b
685 !end of no echo interface
686 ! #endif
687         pop iy
688         pop hl
689         ld (hl),a
690         pop hl
691         ld hl,1
692         push hl
693         ld hl,0
694         push hl ; jr rtn
695 1:
696         ld hl,sibuf+1           ! read from console assumed
697         dec (hl)
698         jp p,2f
699         dec hl                  ! go read console line
700         ld (hl),80              ! max line length
701         push iy
702         push hl
703         ld c,readconsole
704         ex de,hl
705         call bdos
706         ld c,writeconsole
707         ld e,'\n'
708         call bdos
709         pop hl
710         pop iy
711         inc hl
712         inc (hl)
713         ld (siptr),hl           ! ready for transfer
714         push hl
715         ld e,(hl)
716         ld d,0
717         add hl,de
718         ld (hl),'\r'
719         inc hl
720         ld (hl),'\n'
721         pop hl
722 2:
723         push bc
724         pop ix
725         ld b,(hl)
726         inc b                   ! bytes remaining
727         pop hl                  ! copy to
728         pop de                  ! bytes wanted (probably 512)
729         push ix
730         ld ix,(siptr)           ! copy from
731         xor a                   ! find out minimum of ramaining and wanted
732         or d
733         jr nz,3f                ! more than 255 wanted (forget that)
734         ld a,b
735         cp e
736         jp m,3f                 ! not enough remaining
737         ld b,e
738 3:
739         ld c,b                  ! keep copy
740 0:
741         inc ix
742         ld a,(ix)
743         ld (hl),a
744         inc hl
745         djnz 0b
746         ld a,(sibuf+1)
747         sub c
748         inc a
749         ld (sibuf+1),a
750         ld (siptr),ix
751         pop hl
752         push bc
753         ld c,b
754         push bc                 ! load 0
755         ld b,h
756         ld c,l
757         ld ix,(return) ; jp (ix)
758 readfile:
759         call findfile
760         pop de
761         pop hl                  ! count
762         push bc
763         ld bc,0
764 0:
765         xor a
766         or l
767         jr z,1f
768         dec l
769 3:
770 ! warning: this may not work if zcount overflows
771         ld a,(ix+zcount)
772         or a
773         jr nz,5f
774         ld a,(ix+zsave)
775         cp 26
776         jr z,4f
777         ld (ix+zsave),26
778         jr 8f
779 4:
780         call getchar
781         jr c,2f
782         ld (de),a
783         sub 26          ! CTRL-Z
784         jr z,7f
785         ld a,(ix+zcount)
786         or a
787         jr z,6f
788         ld a,(de)
789         ld (ix+zsave),a
790 5:
791         ld a,26
792         dec (ix+zcount)
793 8:
794         ld (de),a
795 6:
796         inc de
797         inc bc
798         jr 0b
799 1:
800         dec l
801         dec h
802         jp p,3b
803 2:
804         pop hl
805         push bc
806         ld b,h
807         ld c,l
808         ld hl,0
809         push hl ; jr rtn
810 7:
811         inc (ix+zcount)
812         jr 4b
813
814 ux_write:
815         pop hl
816         ld a,l
817         sub 3
818         jp p,writefile
819         pop hl                  ! buffer address
820         pop de                  ! count
821         push de
822         ld ix,0
823         push ix
824         push bc
825         ld b,e                  ! count now in 'db'
826 0:
827         ld a,b
828         or a
829         jr nz,1f
830         ld a,d
831         or a
832         jr nz,2f
833         pop bc
834         ld ix,(return) ; jp (ix)
835 2:
836         dec d
837 1:
838         dec b
839         ld e,(hl)
840         inc hl
841         push bc
842         push de
843         push hl
844         ld c,writeconsole
845         call bdos
846         pop hl
847         pop de
848         pop bc
849         jr 0b
850 writefile:
851         call findfile
852         pop de
853         pop hl                  ! count
854         push bc
855         ld bc,0
856 0:
857         xor a
858         or l
859         jr z,1f
860         dec l
861 3:
862         ld a,(de)
863         inc de
864         call putchar
865         jr c,4f
866         inc bc
867         jr 0b
868 1:
869         dec l
870         dec h
871         jp p,3b
872         ld ix,0
873 2:
874         pop hl
875         push bc
876         ld b,h
877         ld c,l
878         push ix
879         ld ix,(return) ; jp (ix)
880 4:
881         ld ix,ENOSPC
882         jr 2b
883
884 ux_unlink:
885         pop hl
886         ld ix,fcb
887         call parsename
888         push bc
889         ld c,delete
890         ld de,fcb
891         call bdos
892         pop bc
893         inc a
894         jr nz,1f
895         ld hl,ENOENT
896         push hl ; jr rtn
897 1:
898         ld hl,0
899         push hl ; jr rtn
900
901 ux_getpid:
902         ld hl,12345             ! nice number
903         push hl ; jr rtn
904
905
906
907
908
909
910 retarea: .data2 0       ! base of buffer for result values (max 8 bytes)
911          .data2 0
912          .data2 0
913          .data2 0
914
915 trapproc:
916         .data2 0
917
918 nextp:  .data1 0
919
920 header:
921 ntext:  .data2 0
922 ndata:  .data2 0
923 nproc:  .data2 0
924 entry:  .data2 0
925 nline:  .data2 0
926
927 hp:     .data2 0
928 pb:     .data2 0
929 pd:     .data2 0