Pristine Ack-5.5
[Ack-5.5.git] / mach / m68k4 / libem / libem_s.a
1 eÿaar.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\1c\ 3.define     .aar
2 .sect .text
3 .sect .rom
4 .sect .data
5 .sect .bss
6
7 .sect .text
8         ! (on entry d0 contains the integer size in the descriptor)
9 .aar:
10         cmp.l   #4, d0
11         beq     9f
12         move.l  #EILLINS, -(sp)
13         jmp     .fatal
14 9:
15         ! register usage:
16         ! a0: descriptor address
17         ! a1: base address
18         ! d0: index
19
20         ! The address is calculated by taking the relative index
21         ! (index - lower bound), multiplying that with the element
22         ! size and adding the result to the array base address.
23
24         move.l  (sp)+,a1        ! return address
25         move.l  (sp)+, a0       ! descriptor address
26         move.l  (sp)+, d0       ! index
27         sub.l   (a0), d0        ! relative index
28         move.l  a1,-(sp)
29         move.l  d0, -(sp)
30         move.l  8(a0), -(sp)    ! # bytes / element
31         jsr     .mlu
32         move.l  (sp)+,a1
33         move.l  (sp)+, a0       ! array base address
34         lea     0(a0, d1.l), a0 ! address of array element
35         jmp     (a1)
36 .align 2
37 lar.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\19\ 4.define       .lar
38 .sect .text
39 .sect .rom
40 .sect .data
41 .sect .bss
42 .sect .text
43         ! (on entry d0 contains the integer size in the descriptor)
44 .lar:
45         cmp.l   #4, d0
46         beq     9f
47         move.l  #EILLINS, -(sp)
48         jmp     .fatal
49 9:
50         ! register usage:
51         ! a0: descriptor address, later base addres
52         ! a1: return address
53         ! d0: index
54         ! d2: #bytes / element
55
56         ! For address calculation; see comment in 'aar.s'.
57
58         move.l  (sp)+, a1       ! return address
59         move.l  (sp)+, a0       ! descriptor address
60         move.l  (sp)+, d0       ! index
61         sub.l   (a0), d0        ! relative index
62         move.l  8(a0), d2       ! #bytes / element
63         move.l  (sp)+, a0       ! array base address
64         clr.l   d1
65         cmp.l   #1, d2
66         bne     2f
67         move.b  0(a0, d0.l), d1 ! one byte element
68         move.l  d1, -(sp)
69         bra     5f
70 2:
71         cmp.l   #2, d2
72         bne     4f
73         asl.l   #1, d0
74         move.w  0(a0, d0.l), d1 ! two byte element
75         move.l  d1, -(sp)
76         bra     5f
77 4:      
78         move.l  a0,-(sp)
79         move.l  d0, -(sp)
80         move.l  d2, -(sp)
81         jsr     .mlu
82         move.l  (sp)+,a0
83         add.l   d1, a0          ! address of 4n byte element
84         add.l   d2, a0          ! because of predecrement
85         asr.l   #2, d2
86         sub.l   #1, d2
87 1:
88         move.l  -(a0), -(sp)
89         dbf     d2, 1b
90 5:
91         jmp     (a1)
92 .align 2
93 \0sar.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\03\ 4.define      .sar
94 .sect .text
95 .sect .rom
96 .sect .data
97 .sect .bss
98
99 .sect .text
100         ! (on entry d0 contains the integer size in the descriptor)
101 .sar:
102         cmp.l   #4, d0
103         beq     9f
104         move.l  #EILLINS, -(sp)
105         jmp     .fatal
106 9:
107         ! register usage:
108         ! a0: descriptor address, later base address
109         ! a1: return address
110         ! d0: index
111         ! d2: # bytes / element
112
113         ! For address calculation; see comment in 'aar.s'.
114         ! If the element size is a fraction of EM_WSIZE (4)
115         ! the calculation is done by adding.
116
117         move.l  (sp)+,a1        ! return address
118         move.l  (sp)+, a0
119         move.l  (sp)+, d0
120         sub.l   (a0), d0
121         move.l  8(a0), d2       ! # bytes / element
122         move.l  (sp)+, a0
123         clr.l   d1
124         cmp.l   #1, d2
125         bne     2f
126         move.l  (sp)+, d1
127         move.b  d1, 0(a0, d0.l) ! store one byte element
128         bra     5f
129 2:
130         cmp.l   #2, d2
131         bne     4f
132         asl.l   #1, d0
133         move.l  (sp)+, d1
134         move.w  d1, 0(a0, d0.l) ! store two byte element
135         bra     5f
136 4:                              ! here: 4n byte element
137         move.l  a0,-(sp)
138         move.l  d0, -(sp)
139         move.l  d2, -(sp)
140         jsr     .mlu
141         move.l  (sp)+,a0
142         add.l   d1, a0          ! address of 4n byte element
143         asr.l   #2, d2
144         sub.l   #1, d2
145 1:
146         move.l  (sp)+, (a0)+
147         dbf     d2, 1b
148 5:
149         jmp     (a1)
150 .align 2
151 \0cii.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0â\ 1.define      .cii
152 .sect .text
153 .sect .rom
154 .sect .data
155 .sect .bss
156
157         .sect .text
158 .cii:
159         move.l  (sp)+,a0        ! return address
160         move.l  (sp)+,d0        ! destination size
161         move.l  (sp)+,d1
162         move.l  (sp),d2
163         cmp.l   #1,d1
164         bne     1f
165         move.l  #2,d1
166         ext.w   d2
167 1:
168         cmp.l   #2,d1
169         bne     1f
170         move.l  #4,d1
171         ext.l   d2
172 1:
173         move.l  d2,(sp)
174         sub.l   d1,d0   
175         bgt     1f
176         sub.l   d0,sp           ! pop extra bytes
177         bra     3f
178 1:
179         clr.l   d1
180         tst.l   d2
181         bge     1f
182         move.l  #-1,d1
183 1:
184         asr     #2,d0
185 2:
186         move.l  d1,-(sp)
187         dbf     d0,2b
188 3:
189         move.l  a0,-(sp)
190         rts
191
192 .align 2
193 cmi.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ê\ 1.define       .cmi
194 .sect .text
195 .sect .rom
196 .sect .data
197 .sect .bss
198
199 .sect .text
200         ! on entry d0: # bytes of 1 block
201         ! on exit d0: result
202 .cmi:
203         move.l  (sp)+, d2       ! return address
204         move.l  sp, a0          ! address of top block
205         lea     0(sp, d0.l), a1 ! address of lower block
206         move.l  d0, d1
207         asr.l   #2, d0
208 1:
209         cmp.l   (a0)+, (a1)+
210         bne     2f
211         sub.l   #1, d0
212         bne     1b
213 2:
214         bge     3f
215         neg.l   d0              ! less
216 3:
217         asl.l   #1, d1
218         add.l   d1, sp          ! new sp; two blocks popped
219         move.l  d2, -(sp)
220         rts
221 .align 2
222 cmp.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0ì\0.define       .cmp
223 .sect .text
224 .sect .rom
225 .sect .data
226 .sect .bss
227
228         .sect .text
229 .cmp:
230         move.l  (sp)+,d2        ! return address
231         move.l  #1,d1
232         move.l  (sp)+,d0
233         cmp.l   (sp)+,d0
234         bne     1f
235         clr.l   d1
236         1:
237         bcs     2f
238         neg.l   d1
239         2:
240         move.l  d2,-(sp)
241         rts
242
243 .align 2
244 cmu.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0é\ 1.define       .cmu
245 .sect .text
246 .sect .rom
247 .sect .data
248 .sect .bss
249
250 .sect .text
251         ! on entry d0: # bytes of 1 block
252         ! on exit d0: result
253 .cmu:
254         move.l  (sp)+, d2       ! return address
255         move.l  sp, a0          ! address of top block
256         lea     0(sp, d0.l), a1 ! address of lower block
257         move.l  d0, d1
258         asr.l   #2, d0
259 1:
260         cmp.l   (a0)+, (a1)+
261         bne     2f
262         sub.l   #1, d0
263         bne     1b              ! note: on equal carry is set
264 2:
265         bcc     3f
266         neg.l   d0              ! less
267 3:
268         asl.l   #1, d1
269         add.l   d1, sp          ! new sp; two blocks popped
270         move.l  d2, -(sp)
271         rts
272 .align 2
273 rcsa.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\ 6\ 2.define .csa4
274 .sect .text
275 .sect .rom
276 .sect .data
277 .sect .bss
278
279         .sect .text
280 .csa4:
281         ! case descriptor in a0
282         ! index in d0
283         move.l  (a0)+,a1        ! default address
284         sub.l   (a0)+,d0        ! index - lower bound
285         blt     1f
286         cmp.l   (a0)+,d0        ! rel. index <-> upper - lower bound
287         bgt     1f
288         asl.l   #2,d0
289         add.l   d0,a0
290         move.l  (a0),d0         ! test jump address
291         beq     1f
292         move.l  d0,-(sp)
293         bra     3f
294 1:
295         move.l  a1,d0           ! test default jump address
296         beq     2f
297         move.l  a1,-(sp)        ! jump address
298 3:
299         rts                     ! not a real rts
300 2:
301         move.l  #ECASE,-(sp)
302         jmp     .fatal
303
304 .align 2
305 csb.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\ 1.define .csb4
306 .sect .text
307 .sect .rom
308 .sect .data
309 .sect .bss
310
311         .sect .text
312 .csb4:
313         ! case descriptor in a0
314         ! index in d0
315         move.l  (a0)+,a1        ! default jump address
316         move.l  (a0)+,d1        ! # entries
317         beq     2f
318         sub.l   #1,d1
319 1:
320         cmp.l   (a0)+,d0
321         beq     3f
322         tst.l   (a0)+           ! skip jump address
323         dbf     d1,1b
324 2:
325         move.l  a1,d1           ! default jump address
326         bne     4f
327         move.l  #ECASE,-(sp)
328         jmp     .fatal
329 3:
330         move.l  (a0)+,a1        ! get jump address
331 4:
332         move.l  a1,-(sp)
333         rts
334 .align 2
335 cuu.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0)\ 1.define       .ciu
336 .define .cui
337 .define .cuu
338 .sect .text
339 .sect .rom
340 .sect .data
341 .sect .bss
342
343         .sect .text
344 .ciu:
345 .cui:
346 .cuu:
347         move.l  (sp)+,a0        ! return address
348         move.l  (sp)+,d0        ! destination size
349         sub.l   (sp)+,d0
350         bgt     1f
351         sub.l   d0,sp
352         jmp     (a0)
353 1:
354         asr.l   #2,d0
355 2:
356         clr.l   -(sp)
357         dbf     d0,2b
358         jmp     (a0)
359
360 .align 2
361 dexg.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\00\ 1.define      .exg
362 .sect .text
363 .sect .rom
364 .sect .data
365 .sect .bss
366
367 .sect .text
368         ! d0 : exchange size in bytes
369 .exg:
370         lea     4(sp, d0), a0   ! address of bottom block
371         lea     4(sp), a1       ! address of top block
372         asr.l   #2, d0
373         sub.l   #1, d0
374 1:
375         move.l  (a1), d1
376         move.l  (a0), (a1)+
377         move.l  d1, (a0)+
378         dbf     d0, 1b
379         rts
380 .align 2
381 inn.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\17\ 2.define       .inn
382 .sect .text
383 .sect .rom
384 .sect .data
385 .sect .bss
386 .sect .text
387
388 .inn:   ! d0 bitnumber
389         ! d1 setsize in bytes
390         ! on exit: 0 or 1 in d0
391
392         move.l  d2, -(sp)
393         move.l  d0, d2
394         asr.l   #3, d2          ! offset .sect from sp in bytes
395         eor.l   #3, d2          ! longs are stored in high-to-low order
396         cmp.l   d1, d2
397         bge     1f              ! bitnumber too large
398         btst    d0, 8(sp, d2.l)
399         beq     2f
400         move.l  #1, d0
401         bra     3f
402 1:
403         move.l  #ESET, -(sp)
404         jsr     .trp
405 2:
406         clr.l   d0
407 3:
408         move.l  (sp)+, d2
409         move.l  (sp)+, a0       ! return address
410         add.l   d1, sp          ! pop bitset
411         jmp     (a0)            ! return
412 .align 2
413 ,lfr.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0,\ 1.define .lfr
414 .sect .text
415 .sect .rom
416 .sect .data
417 .sect .bss
418
419         .sect .text
420 .lfr:
421         move.l (sp)+,a0
422         cmp #2,d7
423         bne 1f
424         move d0,-(sp)
425         bra 3f
426 1:
427         cmp #4,d7
428         bne 2f
429         move.l d0,-(sp)
430         bra 3f
431 2:
432         cmp #8,d7
433         bne 4f
434         move.l d1,-(sp)
435         move.l d0,-(sp)
436 3:
437         jmp(a0)
438 4:
439         move.l  #EILLINS,-(sp)
440         jmp     .fatal
441 .align 2
442 los.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ë\ 1.define .los
443 .sect .text
444 .sect .rom
445 .sect .data
446 .sect .bss
447
448         ! d0 : # bytes
449         ! a0 : source address
450         .sect .text
451 .los:
452         move.l  (sp)+,a1
453         move.l  (sp)+,d0
454         move.l  (sp)+,a0
455         cmp.l   #1,d0
456         bne     1f
457         clr.l   d0              !1 byte
458         move.b  (a0),d0
459         move.l  d0,-(sp)
460         bra     3f
461 1:
462         cmp.l   #2,d0
463         bne     2f
464         clr.l   d0              !2 bytes
465         add.l   #2,a0
466         move.w  (a0),d0
467         move.l  d0,-(sp)
468         bra     3f
469 2:
470         add.l   d0,a0           !>=4 bytes
471         asr.l   #2,d0
472
473 4:      move.l  -(a0),-(sp)     
474         sub.l   #1,d0
475         bgt     4b
476 3:
477         jmp     (a1)
478 .align 2
479 0rck.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0ÿ\0.define .rck
480 .sect .text
481 .sect .rom
482 .sect .data
483 .sect .bss
484
485         .sect .text
486 .rck:
487         move.l  (sp)+,a1
488         move.l  (sp)+,a0        ! descriptor address
489         move.l  (sp),d0
490         cmp.l   (a0),d0
491         blt     1f
492         cmp.l   4(a0),d0
493         ble     2f
494 1:
495         move.l  #ERANGE,-(sp)
496         jsr     .trp
497 2:
498         jmp     (a1)
499
500 .align 2
501 mret.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0(\ 1.define .ret
502 .sect .text
503 .sect .rom
504 .sect .data
505 .sect .bss
506
507         .sect .text
508 .ret:
509         beq 3f
510         cmp #2,d0
511         bne 1f
512         move (sp)+,d0
513         bra 3f
514 1:
515         cmp #4,d0
516         bne 2f
517         move.l (sp)+,d0
518         bra 3f
519 2:
520         cmp #8,d0
521         bne 4f
522         move.l (sp)+,d0
523         move.l (sp)+,d1
524 3:
525         unlk a6
526         rts
527 4:
528         move.l  #EILLINS,-(sp)
529         jmp     .fatal
530 .align 2
531 set.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ñ\ 1.define       .set
532 .sect .text
533 .sect .rom
534 .sect .data
535 .sect .bss
536
537 .sect .text
538 .set:   ! d0 bitnumber
539         ! d1 setsize in bytes
540
541         move.l  (sp)+,a0
542         move.l  d1, d2
543         asr.l   #2, d2
544         sub.l   #1, d2
545 1:
546         clr.l   -(sp)
547         dbf     d2, 1b
548
549         move.l  d0, d2
550         asr.l   #3, d2          ! offset .sect from sp in bytes
551         eor.l   #3, d2          ! longs are stored in high-to-low order
552         cmp.l   d1, d2
553         blt     2f
554         move.l  a0, -(sp)
555         move.l  #ESET, -(sp)    ! bitnumber too large
556         jsr     .trp
557         rts
558 2:
559         bset    d0, 0(sp, d2.l)
560         jmp     (a0)
561 .align 2
562 tsts.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\89\ 1.define .sts
563 .sect .text
564 .sect .rom
565 .sect .data
566 .sect .bss
567
568         ! d0 : # bytes
569         ! a0 : destination address
570         .sect .text
571 .sts:
572         move.l  (sp)+,a1
573         move.l  (sp)+,d0
574         move.l  (sp)+,a0
575         cmp     #1,d0
576         bne     1f
577         move.l  (sp)+,d0
578         move.b  d0,(a0)
579         bra     4f
580
581 1:      cmp     #2,d0
582         bne     2f
583         move.l  (sp)+,d0
584         add.l   #2,a0
585         move.w  d0,(a0)
586         bra     4f
587 2:
588         asr     #2,d0
589         sub.l   #1,d0
590 3:
591         move.l  (sp)+,(a0)+
592         dbf     d0,3b
593 4:
594         jmp     (a1)
595 .align 2
596 enop.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ñ\0.define .nop
597 .sect .text
598 .sect .rom
599 .sect .data
600 .sect .bss
601
602 .sect .text
603 .nop:
604         pea     4(sp)
605         move.l  .lino,-(sp)
606         pea     fmt
607         jsr     .diagnos
608         lea     12(sp),sp
609         rts
610
611         .sect .data
612 fmt:    .asciz "test %d, sp 0x%x.\n"
613 .align 2
614
615 mon.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ó\0.define .mon
616 .sect .text
617 .sect .rom
618 .sect .data
619 .sect .bss
620
621 .sect .text
622 .mon:
623         move.l  (sp)+,a0
624         pea     fmt
625         jsr     .diagnos
626         add.l   #8,sp
627         jmp     EXIT
628
629         .sect .data
630 fmt:    .asciz "system call %d not implemented\n"
631 .align 2
632 mdvi.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\8d\v.define .dvi
633 .sect .text
634 .sect .rom
635 .sect .data
636 .sect .bss
637
638  ! signed long divide
639  !-----------------------------------------------------------------------------
640  ! rewritten by Kai-Uwe Bloem (i5110401@dbstu1.bitnet) for speed.
641  !   #1  01/12/90  initial revision. Minor reduce of shift operations.
642  !   #2  03/07/90  use 68000 divu instruction whereever possible. This change
643  !                 makes #1 superflous. (derived from my GNU division routine)
644  !-----------------------------------------------------------------------------
645  ! Some common cases can be handled in a special, much faster way :
646  !      1) divisor = 0
647  !          => cause trap, then return to user. Result is undefined
648  !      2) dividend < divisor
649  !          => quotient = 0, remainder = dividend
650  !      3) divisor < 0x10000 ( i.e. divisor is only 16 bits wide )
651  !          => quotient and remainder can be calculated quite fast by repeated
652  !             application of 68000 divu operations (ca. 400 cycles)
653  !      4) otherwise (due to #2, #3 dividend, divisor both wider then 16 bits)
654  !          => do slow division by shift and subtract
655  !-----------------------------------------------------------------------------
656
657
658  ! register usage:
659  !       : d0 divisor
660  !         d1 dividend
661  ! exit  : d1 quotient
662  !         d2 remainder
663
664         .sect .text
665 .dvi:
666         move.l  (sp)+,a1        ! return address
667         move.l  (sp)+,d0        ! divisor
668         move.l  (sp)+,d2        ! dividend
669         move.l  d3,a0           ! save d3
670         move.l  d4,-(sp)        ! save result sign register
671         clr.l   d4
672         tst.l   d2
673         bpl     0f              ! dividend is negative ?
674         neg.l   d2              ! yes - negate
675         not.l   d4              ! and note negation in d4
676 0:
677         tst.l   d0
678         bpl     0f              ! divisor is negative ?
679         neg.l   d0              ! yes - negate
680         not.w   d4              ! note negation
681 0:
682         clr.l   d1              ! prepare quotient
683 ! === case 1: divisor = 0
684         tst.l   d0              ! divisor = 0 ?
685         beq     9f              ! yes - divide by zero trap
686 ! === case 2: dividend < divisor
687         cmp.l   d0,d2           ! dividend < divisor ?
688         bcs     8f              ! yes - division already finished
689 ! === case 3: divisor <= 0x0ffff
690         cmp.l   #0x0ffff,d0     ! is divisor only 16 bits wide ?
691         bhi     2f
692         move.w  d2,d3           ! save dividend.l
693         clr.w   d2              ! prepare dividend.h for divu operation
694         swap    d2
695         beq     0f              ! dividend.h is all zero, no divu necessary
696         divu    d0,d2
697 0:      move.w  d2,d1           ! save quotient.h
698         swap    d1
699         move.w  d3,d2           ! divide dividend.l
700         divu    d0,d2           ! (d2.h = remainder of prev divu)
701         move.w  d2,d1           ! save qoutient.l
702         clr.w   d2              ! get remainder
703         swap    d2
704         bra     8f
705 ! === case 4: divisor and dividend both > 0x0ffff
706 2:
707         move    #32-1,d3        ! loop count
708 4:
709         lsl.l   #1,d2           ! shift dividend ...
710         roxl.l  #1,d1           !  ... into d1
711         cmp.l   d0,d1           ! compare with divisor
712         bcs     5f
713         sub.l   d0,d1           ! bigger, subtract divisor
714         add     #1,d2           ! note subtraction in result
715 5:
716         dbra    d3,4b
717         exg     d1,d2           ! get results in the correct registers
718 8:
719         tst.w   d4              ! quotient < 0 ?
720         bpl     0f
721         neg.l   d1              ! yes - negate
722 0:      tst.l   d4              ! remainder < 0 ?
723         bpl     0f
724         neg.l   d2
725 0:      move.l  (sp)+,d4        ! restore d4
726         move.l  a0,d3           ! restore d3
727         jmp     (a1)
728
729 EIDIVZ  = 6
730 9:      move.w  #EIDIVZ,-(sp)
731         jsr     .trp
732 \0mli.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0p\ 1.define .mli
733 .sect .text
734 .sect .rom
735 .sect .data
736 .sect .bss
737
738
739         .sect .text
740 .mli:
741         move.l  4(sp),d1
742         move.l  8(sp),d0
743         move.l  d5,-(sp)
744         clr     d5
745         tst.l   d0
746         bpl     1f
747         neg.l   d0
748         not     d5
749 1:
750         tst.l   d1
751         bpl     2f
752         neg.l   d1
753         not     d5
754 2:
755         move.l  d0,-(sp)
756         move.l  d1,-(sp)
757         jsr     .mlu
758         tst     d5
759         beq     3f
760         neg.l   d1
761         negx.l  d0
762 3:
763         move.l  (sp)+,d5
764         move.l  (sp)+,a0
765         add.l   #8,sp
766         jmp     (a0)
767
768 .align 2
769 mlu.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\92\ 2.define .mlu
770 .sect .text
771 .sect .rom
772 .sect .data
773 .sect .bss
774
775  ! entry : d0 multiplicand
776  !         d1 multiplier
777  ! exit  : d0 high order result
778  !         d1 low order result
779
780         .sect .text
781 .mlu:
782         movem.l d3/d4/d6,-(sp)
783         move.l  16(sp),d1
784         move.l  20(sp),d0
785         cmp.l   #32768,d0
786         bgt     1f
787         cmp.l   #32768,d1
788         bls     2f
789 1:
790         move.l  d1,d3
791         move.l  d1,d2
792         swap    d2
793         move.l  d2,d4
794         mulu    d0,d1
795         mulu    d0,d2
796         swap    d0
797         mulu    d0,d3
798         mulu    d4,d0
799         clr.l   d6
800         swap    d1
801         add     d2,d1
802         addx.l  d6,d0
803         add     d3,d1
804         addx.l  d6,d0
805         swap    d1
806         clr     d2
807         clr     d3
808         swap    d2
809         swap    d3
810         add.l   d2,d0
811         add.l   d3,a0
812         bra     3f
813 2:      mulu    d0,d1
814         clr     d0
815 3:
816         movem.l (sp)+,d3/d4/d6
817         move.l  (sp)+,a0
818         add     #8,sp
819         jmp     (a0)
820 .align 2
821 shp.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ý\ 1.define       .strhp
822 .sect .text
823 .sect .rom
824 .sect .data
825 .sect .bss
826
827         .sect .text
828 .strhp:
829         move.l  4(sp), d1       ! new heap pointer
830         cmp.l   .limhp, d1
831         blt     1f
832         add.l   #0x400, d1
833         and.l   #~0x3ff, d1
834         move.l  d1, -(sp)
835         move.l  d1,.limhp
836         jsr     BRK             ! allocate 1K bytes of extra storage
837         add.l   #4, sp
838         tst.l   d0
839         bne     2f
840 1:
841         move.l  4(sp), .reghp   ! store new value of heap pointer
842         move.l  (sp)+,a0
843         move.l  a0,(sp)
844         rts
845 2:
846         move.l  #EHEAP, -(sp)
847         jsr     .trp
848         move.l  (sp)+,a0
849         move.l  a0,(sp)
850         rts
851 .align 2
852 lsig.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0µ\0.define      .sig
853 .sect .text
854 .sect .rom
855 .sect .data
856 .sect .bss
857
858         .sect .text
859 .sig:
860         move.l  (sp)+,a0
861         move.l  (sp)+,a1        ! trap pc
862         move.l  .trppc,-(sp)
863         move.l  a1,.trppc
864         jmp     (a0)
865 .align 2
866 1cms.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0¼\ 1.define      .cms
867 .sect .text
868 .sect .rom
869 .sect .data
870 .sect .bss
871
872 .sect .text
873         ! d0 contains set size
874         ! on exit d0 is zero for equal, non-zero for not equal
875 .cms:
876         move.l  (sp)+, d2       ! return address
877         move.l  sp, a0          ! address of top block
878         lea     0(sp, d0.l), a1 ! address of lower block
879         move.l  d0, d1
880         asr.l   #2, d0
881 1:
882         cmp.l   (a0)+, (a1)+
883         bne     2f
884         sub.l   #1, d0
885         bne     1b
886 2:
887         asl.l   #1, d1
888         add.l   d1, sp          ! two blocks popped
889         move.l  d2, -(sp)
890         rts
891 .align 2
892 fat.s\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0q\0.define       .fatal
893 .sect .text
894 .sect .rom
895 .sect .data
896 .sect .bss
897
898         .sect .text
899 .fatal:
900         jsr     .trp    
901         jmp     EXIT
902 .align 2
903 zfp68881.s\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0À\ f.define .adf4, .adf8, .sbf4, .sbf8, .mlf4, .mlf8, .dvf4, .dvf8
904 .define .ngf4, .ngf8, .fif4, .fif8, .fef4, .fef8
905 .define .cif4, .cif8, .cuf4, .cuf8, .cfi, .cfu, .cff4, .cff8
906 .define .cmf4, .cmf8
907 .sect .text
908 .sect .rom
909 .sect .data
910 .sect .bss
911
912 !       $Id: fp68881.s,v 1.2 1994/06/24 13:05:14 ceriel Exp $
913
914 !       Implement interface to floating point package for M68881
915
916         .sect .text
917 .adf4:
918         move.l  (sp)+,a0
919         fmove.s (sp),fp0
920         fadd.s  4(sp),fp0
921         fmove.s fp0,4(sp)
922         jmp     (a0)
923
924 .adf8:
925         move.l  (sp)+,a0
926         fmove.d (sp),fp0
927         fadd.d  8(sp),fp0
928         fmove.d fp0,8(sp)
929         jmp     (a0)
930
931 .sbf4:
932         move.l  (sp)+,a0
933         fmove.s (sp),fp0
934         fmove.s 4(sp),fp1
935         fsub    fp0,fp1
936         fmove.s fp1,4(sp)
937         jmp     (a0)
938
939 .sbf8:
940         move.l  (sp)+,a0
941         fmove.d (sp),fp0
942         fmove.d 8(sp),fp1
943         fsub    fp0,fp1
944         fmove.d fp1,8(sp)
945         jmp     (a0)
946
947 .mlf4:
948         move.l  (sp)+,a0
949         fmove.s (sp),fp0
950         fmul.s  4(sp),fp0
951         fmove.s fp0,4(sp)
952         jmp     (a0)
953
954 .mlf8:
955         move.l  (sp)+,a0
956         fmove.d (sp),fp0
957         fmul.d  8(sp),fp0
958         fmove.d fp0,8(sp)
959         jmp     (a0)
960
961 .dvf4:
962         move.l  (sp)+,a0
963         fmove.s (sp),fp0
964         fmove.s 4(sp),fp1
965         fdiv    fp0,fp1
966         fmove.s fp1,4(sp)
967         jmp     (a0)
968
969 .dvf8:
970         move.l  (sp)+,a0
971         fmove.d (sp),fp0
972         fmove.d 8(sp),fp1
973         fdiv    fp0,fp1
974         fmove.d fp1,8(sp)
975         jmp     (a0)
976
977 .ngf4:
978         fmove.s 4(sp),fp0
979         fneg    fp0
980         fmove.s fp0,4(sp)
981         rts
982
983 .ngf8:
984         fmove.d 4(sp),fp0
985         fneg    fp0
986         fmove.d fp0,4(sp)
987         rts
988
989 .fif4:
990         move.l  (sp)+,a0
991         move.l  (sp),a1
992         fmove.s 4(sp),fp0
993         fmove.s 8(sp),fp1
994         fmul    fp0,fp1
995         fintrz  fp1,fp0
996         fsub    fp0,fp1
997         fmove.s fp1,4(a1)
998         fmove.s fp0,(a1)
999         jmp     (a0)
1000
1001 .fif8:
1002         move.l  (sp)+,a0
1003         move.l  (sp),a1
1004         fmove.d 4(sp),fp0
1005         fmove.d 12(sp),fp1
1006         fmul    fp0,fp1
1007         fintrz  fp1,fp0
1008         fsub    fp0,fp1
1009         fmove.d fp1,8(a1)
1010         fmove.d fp0,(a1)
1011         jmp     (a0)
1012
1013 .fef4:
1014         move.l  (sp)+,a0
1015         move.l  (sp),a1
1016         fmove.s 4(sp),fp0
1017         fgetexp fp0,fp1
1018         fmove.l fpsr,d0
1019         and.l   #0x2000,d0      ! set if Infinity
1020         beq     1f
1021         move.l  #129,(a1)
1022         fmove.s 4(sp),fp0
1023         fblt    2f
1024         move.l  #0x3f000000,4(a1)
1025         jmp     (a0)
1026 2:
1027         move.l  #0xbf000000,4(a1)
1028         jmp     (a0)
1029 1:
1030         fmove.l fp1,d0
1031         add.l   #1,d0
1032         fgetman fp0
1033         fbne    1f
1034         clr.l   d0
1035         bra     2f
1036 1:
1037         fmove.l #2,fp1
1038         fdiv    fp1,fp0
1039 2:
1040         fmove.s fp0,4(a1)
1041         move.l  d0,(a1)
1042         jmp     (a0)
1043
1044 .fef8:
1045         move.l  (sp)+,a0
1046         move.l  (sp),a1
1047         fmove.d 4(sp),fp0
1048         fgetexp fp0,fp1
1049         fmove.l fpsr,d0
1050         and.l   #0x2000,d0      ! set if Infinity
1051         beq     1f
1052         move.l  #1025,(a1)
1053         fmove.d 4(sp),fp0
1054         fblt    2f
1055         move.l  #0x3fe00000,4(a1)
1056         clr.l   8(a1)
1057         jmp     (a0)
1058 2:
1059         move.l  #0xbfe00000,4(a1)
1060         clr.l   8(a1)
1061         jmp     (a0)
1062 1:
1063         fmove.l fp1,d0
1064         add.l   #1,d0
1065         fgetman fp0
1066         fbne    1f
1067         clr.l   d0
1068         bra     2f
1069 1:
1070         fmove.l #2,fp1
1071         fdiv    fp1,fp0
1072 2:
1073         fmove.d fp0,4(a1)
1074         move.l  d0,(a1)
1075         jmp     (a0)
1076
1077 .cif4:
1078         move.l  (sp)+,a0
1079         fmove.l 4(sp),fp0
1080         fmove.s fp0,4(sp)
1081         jmp     (a0)
1082
1083 .cif8:
1084         move.l  (sp)+,a0
1085         fmove.l 4(sp),fp0
1086         fmove.d fp0,(sp)
1087         jmp     (a0)
1088
1089 .cuf4:
1090         move.l  (sp)+,a0
1091         fmove.l 4(sp),fp0
1092         tst.l   4(sp)
1093         bge     1f
1094         fsub.l  #-2147483648,fp0
1095         fsub.l  #-2147483648,fp0
1096 1:
1097         fmove.s fp0,4(sp)
1098         jmp     (a0)
1099
1100 .cuf8:
1101         move.l  (sp)+,a0
1102         fmove.l 4(sp),fp0
1103         tst.l   4(sp)
1104         bge     1f
1105         fsub.l  #-2147483648,fp0
1106         fsub.l  #-2147483648,fp0
1107 1:
1108         fmove.d fp0,(sp)
1109         jmp     (a0)
1110
1111 .cfi:
1112         move.l  (sp)+,a0
1113         move.l  4(sp),d0
1114         cmp.l   #4,d0
1115         bne     1f
1116         fmove.s 8(sp),fp0
1117         fintrz  fp0,fp0
1118         fmove.l fp0,8(sp)
1119         jmp     (a0)
1120 1:
1121         fmove.d 8(sp),fp0
1122         fintrz  fp0,fp0
1123         fmove.l fp0,12(sp)
1124         jmp     (a0)
1125
1126 .cfu:
1127         move.l  (sp)+,a0
1128         move.l  4(sp),d0
1129         cmp.l   #4,d0
1130         bne     1f
1131         fmove.s 8(sp),fp0
1132         fabs    fp0
1133         cmp.l   #0x4f000000,8(sp)
1134         bge     2f
1135         fintrz  fp0,fp0
1136         fmove.l fp0,8(sp)
1137         jmp     (a0)
1138 2:
1139         fadd.l  #-2147483648,fp0
1140         fintrz  fp0,fp0
1141         fmove.l fp0,d0
1142         bchg    #31,d0
1143         move.l  d0,8(sp)
1144         jmp     (a0)
1145 1:
1146         fmove.d 8(sp),fp0
1147         fabs    fp0
1148         cmp.l   #0x41e00000,8(sp)
1149         bge     1f
1150         fintrz  fp0,fp0
1151         fmove.l fp0,12(sp)
1152         jmp     (a0)
1153 1:
1154         fadd.l  #-2147483648,fp0
1155         fintrz  fp0,fp0
1156         fmove.l fp0,d0
1157         bchg    #31,d0
1158         move.l  d0,12(sp)
1159         jmp     (a0)
1160
1161 .cff4:
1162         move.l  (sp)+,a0
1163         fmove.d (sp),fp0
1164         fmove.s fp0,4(sp)
1165         jmp     (a0)
1166
1167 .cff8:
1168         move.l  (sp)+,a0
1169         fmove.s (sp),fp0
1170         fmove.d fp0,(sp)
1171         jmp     (a0)
1172
1173 .cmf4:
1174         move.l  (sp)+,a0
1175         clr.l   d0
1176         fmove.s (sp),fp0
1177         fmove.s 4(sp),fp1
1178         fcmp    fp0,fp1
1179         fbeq    2f
1180         fblt    1f
1181         add.l   #1,d0
1182         jmp     (a0)
1183 1:
1184         sub.l   #1,d0
1185 2:
1186         jmp     (a0)
1187
1188 .cmf8:
1189         move.l  (sp)+,a0
1190         clr.l   d0
1191         fmove.d (sp),fp0
1192         fmove.d 8(sp),fp1
1193         fcmp    fp0,fp1
1194         fbeq    2f
1195         fblt    1f
1196         add.l   #1,d0
1197         jmp     (a0)
1198 1:
1199         sub.l   #1,d0
1200 2:
1201         jmp     (a0)
1202 trp.s\01.s\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0ó\ 1.define       .trp
1203 .sect .text
1204 .sect .rom
1205 .sect .data
1206 .sect .bss
1207
1208         .sect .text
1209 .trp:
1210         move.l  d0,-(sp)
1211         cmp.l   #16,8(sp)
1212         bcc     1f
1213         move.l  8(sp),d0
1214         btst    d0,.trpim
1215         bne     3f
1216 1:
1217         move.l  a0,-(sp)
1218         move.l  .trppc,a0
1219         move.l  a0,d0
1220         beq     9f
1221         clr.l   .trppc
1222         move.l  12(sp),-(sp)
1223         jsr     (a0)
1224         add.l   #4,sp
1225         move.l  (sp)+,a0
1226 3:
1227         move.l  (sp)+,d0
1228         move.l  (sp)+,(sp)
1229         rts
1230 9:
1231         move.l  (sp)+,a0
1232         move.l  (sp)+,d0
1233         move.l  4(sp),-(sp)
1234         pea     fmt
1235         jsr     .diagnos
1236         add     #4,sp
1237         jmp     EXIT
1238
1239         .sect .data
1240 fmt:    .asciz "EM trap %d called\n"
1241 .align 2
1242 fdia.s\01.s\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\r\b.define      .diagnos
1243 .sect .text
1244 .sect .rom
1245 .sect .data
1246 .sect .bss
1247
1248 space   = 040
1249 del     = 0177
1250
1251         .sect .text
1252 .diagnos:
1253         move.l  hol0,-(sp)
1254         move.l  hol0+4,d2
1255         beq     1f
1256         move.l  d2,a0
1257         move.l  #40,d0
1258 3:
1259         move.b  (a0)+,d1
1260         beq     2f
1261         cmp.b   #del,d1
1262         bge     1f
1263         cmp.b   #space,d1
1264         blt     1f
1265         sub     #1,d0
1266         bgt     3b
1267         clr.b   (a0)
1268 2:
1269         move.l  d2,-(sp)
1270         pea     fmt
1271         jsr     printf
1272         add     #12,sp
1273         jmp     printf
1274
1275 1:
1276         move.l  #unknwn,d2
1277         bra     2b
1278
1279 .sect .bss
1280 getal:
1281         .space  12
1282 char:
1283         .space  1
1284         .align  4
1285 .sect .data
1286 hexs:
1287         .ascii  "0123456789abcdef"
1288         .align  4
1289 .sect .text
1290 printf:
1291         movem.l d0/d1/d2/a0/a1/a2/a3/a4/a5/a6, -(sp)
1292         lea     44(sp), a6      ! a6 <- address of arguments
1293         move.l  (a6)+, a5       ! a5 <- address of format
1294 next:   move.b  (a5)+, d0
1295         beq     out
1296         cmp.b   #'%', d0
1297         beq     procnt
1298 put:    move.l  d0, -(sp)
1299         jsr     putchar         ! long argument on stack
1300         tst.l   (sp)+
1301         bra     next
1302
1303 procnt: move.b  (a5)+, d0
1304         cmp.b   #'d', d0        ! NOTE: %d means unsigned.
1305         beq     digit
1306         cmp.b   #'x', d0
1307         beq     hex
1308         cmp.b   #'s', d0
1309         beq     string
1310         cmp.b   #'%', d0        ! second % has to be printed.
1311         beq     put
1312         tst.b   -(a5)           ! normal char should be printed
1313         bra     next
1314
1315 string: move.l  (a6)+, a2       ! a2 <- address of string
1316 sloop:  move.b  (a2)+, d0
1317         beq     next
1318         move.l  d0, -(sp)
1319         jsr     putchar         ! long argument on stack
1320         tst.l   (sp)+
1321         bra     sloop
1322
1323 digit:  move.l  (a6)+, d1       ! d1 <- integer
1324         move.l  #getal+12, a2   ! a2 <- ptr to last part of buf
1325         clr.b   -(a2)           ! stringterminator
1326 1:      
1327         move.l  d1,-(sp)
1328         move.l  #10,-(sp)
1329         jsr     .dvu            ! d1 <- qotient; d0 <- remainder
1330         add.l   #'0', d0
1331         move.b  d0, -(a2)
1332         tst.l   d1              ! if quotient = 0 then ready
1333         bne     1b
1334         bra     sloop           ! print digitstring.
1335
1336 hex:    move.l  (a6)+, d1       ! d1 <- integer
1337         move.l  #getal+12, a2   ! a2 <- ptr to last part of buf
1338         clr.b   -(a2)           ! stringterminator
1339         move.l  #7, d2          ! loop control
1340 1:      move.l  d1, d0
1341         and.l   #15, d0
1342         move.l  #hexs,a0
1343         add.l   d0,a0
1344         move.b  (a0), -(a2) ! hex digit
1345         asr.l   #4, d1
1346         dbf     d2, 1b
1347         bra     sloop
1348
1349 out:
1350         movem.l (sp)+, d0/d1/d2/a0/a1/a2/a3/a4/a5/a6
1351         rts
1352
1353
1354 putchar:
1355         move.l  #1, -(sp)
1356         pea     11(sp)
1357         move.l  #1, -(sp)
1358         jsr     WRITE
1359         lea     12(sp), sp
1360         rts
1361 .align 2
1362         .sect .data
1363 fmt:    .asciz "%s, line %d: "
1364 unknwn: .asciz "unknown file"
1365 .align 2
1366 )dvu.s\01.s\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0ø      .define .dvu
1367 .sect .text
1368 .sect .rom
1369 .sect .data
1370 .sect .bss
1371
1372  ! unsigned long divide
1373  !-----------------------------------------------------------------------------
1374  ! rewritten by Kai-Uwe Bloem (i5110401@dbstu1.bitnet) for speed.
1375  !   #1  01/12/90  initial revision. Minor reduce of shift operations.
1376  !   #2  03/07/90  use 68000 divu instruction whereever possible. This change
1377  !                 makes #1 superflous. (derived from my GNU division routine)
1378  !-----------------------------------------------------------------------------
1379  ! Some common cases can be handled in a special, much faster way :
1380  !      1) divisor = 0
1381  !          => cause trap, then return to user. Result is undefined
1382  !      2) dividend < divisor
1383  !          => quotient = 0, remainder = dividend
1384  !      3) divisor < 0x10000 ( i.e. divisor is only 16 bits wide )
1385  !          => quotient and remainder can be calculated quite fast by repeated
1386  !             application of 68000 divu operations (ca. 400 cycles)
1387  !      4) otherwise (due to #2, #3 dividend, divisor both wider then 16 bits)
1388  !          => do slow division by shift and subtract
1389  !-----------------------------------------------------------------------------
1390
1391
1392  ! register usage:
1393  !       : d0 divisor
1394  !         d1 dividend
1395  ! exit  : d1 quotient
1396  !         d2 remainder
1397
1398         .sect .text
1399 .dvu:
1400         move.l  d3,a0           ! save d3
1401         move.l  (sp)+,a1        ! return address
1402         move.l  (sp)+,d0        ! divisor
1403         move.l  (sp)+,d2        ! dividend
1404         clr.l   d1              ! prepare quotient
1405 ! === case 1: divisor = 0
1406         tst.l   d0              ! divisor = 0 ?
1407         beq     9f              ! yes - divide by zero trap
1408 ! === case 2: dividend < divisor
1409         cmp.l   d0,d2           ! dividend < divisor ?
1410         bcs     8f              ! yes - division already finished
1411 ! === case 3: divisor <= 0x0ffff
1412         cmp.l   #0x0ffff,d0     ! is divisor only 16 bits wide ?
1413         bhi     2f
1414         move.w  d2,d3           ! save dividend.l
1415         clr.w   d2              ! prepare dividend.h for divu operation
1416         swap    d2
1417         beq     0f              ! dividend.h is all zero, no divu necessary
1418         divu    d0,d2
1419 0:      move.w  d2,d1           ! save quotient.h
1420         swap    d1
1421         move.w  d3,d2           ! divide dividend.l
1422         divu    d0,d2           ! (d2.h = remainder of prev divu)
1423         move.w  d2,d1           ! save qoutient.l
1424         clr.w   d2              ! get remainder
1425         swap    d2
1426         bra     8f
1427 ! === case 4: divisor and dividend both > 0x0ffff
1428 2:
1429         move    #32-1,d3        ! loop count
1430 4:
1431         lsl.l   #1,d2           ! shift dividend ...
1432         roxl.l  #1,d1           !  ... into d1
1433         cmp.l   d0,d1           ! compare with divisor
1434         bcs     5f
1435         sub.l   d0,d1           ! bigger, subtract divisor
1436         add     #1,d2           ! note subtraction in result
1437 5:
1438         dbra    d3,4b
1439         exg     d1,d2           ! get results in the correct registers
1440 8:
1441         move.l  a0,d3           ! restore d3
1442         jmp     (a1)
1443
1444 EIDIVZ  = 6
1445 9:      move.w  #EIDIVZ,-(sp)
1446         jsr     .trp