inn.s
fat.s
trp.s
+trpstr.s
mon.s
nop.s
dia.s
-printf.s
cii.s
cuu.s
cmi.s
pr:
@arch pv libem_s.a | pr -h `pwd`/libem_s.a
@pr `pwd`/end.s
+
+trpstr.s: trpstr.c strscript
+ sh strscript
.sect .data
.sect .bss
.sect .text
+EILLINS = 18
.aar: ! (on entry d0 contains the integer size in the descriptor)
! on entry d0: # bytes in 1 block
! on exit d0: result
.cmi:
- move.l (sp)+, d2 ! return address
+ move.l (sp)+, d1 ! return address
move.l sp, a0 ! address of top block
lea (sp,d0.l), a1 ! address of lower block
+ move.l d1,-(sp)
move.l d0, d1
asr.l #2, d0
1:
bge 3f
neg.l d0 ! less
3:
+ move.l (sp)+,a0
lea (sp,d1.l*2), sp ! new sp; two blocks popped
- move.l d2,a0
jmp (a0) ! return
.align 2
! d0 contains set size
! on exit d0 is zero for equal, non-zero for not equal
.cms:
- move.l (sp)+, d2 ! return address
+ move.l (sp)+, d1 ! return address
move.l sp, a0 ! address of top block
lea (sp,d0.l), a1 ! address of lower block
+ move.l d1,-(sp)
move.l d0, d1
asr.l #2, d0
1:
sub.l #1, d0
bne 1b
2:
+ move.l (sp)+,a0
lea (sp,d1.l*2), sp ! new sp; two blocks popped
- move.l d2,a0
jmp (a0)
.align 2
! on entry d0: # bytes in 1 block
! on exit d0: result
.cmu:
- move.l (sp)+, d2 ! return address
+ move.l (sp)+, d1 ! return address
move.l sp, a0 ! address of top block
lea (sp,d0.l), a1 ! address of lower block
+ move.l d1,-(sp)
move.l d0, d1
asr.l #2, d0
1:
bcc 3f
neg.l d0 ! less
3:
+ move.l (sp)+,a0
lea (sp,d1.l*2), sp ! new sp; two blocks popped
- move.l d2, a0
jmp (a0)
.align 2
.sect .rom
.sect .data
.sect .bss
+ECASE=20
.sect .text
.sect .rom
.sect .data
.sect .bss
+ECASE=20
.sect .text
move.l #unknwn, d2
bra 2b
+.sect .bss
+_getal:
+ .space 12
+_char:
+ .space 1
+ .align 4
+.sect .data
+hexs:
+ .ascii "0123456789abcdef"
+ .align 4
+.sect .text
+_printf:
+ movem.l d0/d1/d2/a0/a1/a2/a3/a4/a5/a6, -(sp)
+ lea (44, sp), a6 ! a6 <- address of arguments
+ move.l (a6)+, a5 ! a5 <- address of format
+next: move.b (a5)+, d0
+ beq out
+ cmp.b #'%', d0
+ beq procnt
+put: move.l d0, -(sp)
+ jsr (_putchar) ! long argument on stack
+ tst.l (sp)+
+ bra next
+
+procnt: move.b (a5)+, d0
+ cmp.b #'d', d0 ! NOTE: %d means unsigned.
+ beq digit
+ cmp.b #'x', d0
+ beq hex
+ cmp.b #'s', d0
+ beq string
+ cmp.b #'%', d0 ! second % has to be printed.
+ beq put
+ tst.b -(a5) ! normal char should be printed
+ bra next
+
+string: move.l (a6)+, a2 ! a2 <- address of string
+sloop: move.b (a2)+, d0
+ beq next
+ move.l d0, -(sp)
+ jsr (_putchar) ! long argument on stack
+ tst.l (sp)+
+ bra sloop
+
+digit: move.l (a6)+, d1 ! d1 <- integer
+ move.l #_getal+12, a2 ! a2 <- ptr to last part of buf
+ clr.b -(a2) ! stringterminator
+1: divul.l #10, d2:d1 ! d1 <- qotient; d2 <- remainder
+ add.l #'0', d2
+ move.b d2, -(a2)
+ tst.l d1 ! if quotient = 0 then ready
+ bne 1b
+ bra sloop ! print digitstring.
+
+hex: move.l (a6)+, d1 ! d1 <- integer
+ move.l #_getal+12, a2 ! a2 <- ptr to last part of buf
+ clr.b -(a2) ! stringterminator
+ move.l #7, d2 ! loop control
+1: move.l d1, d0
+ and.l #15, d0
+ move.b (hexs,d0.w), -(a2) ! hex digit
+ asr.l #4, d1
+ dbf d2, 1b
+ bra sloop
+
+out:
+ movem.l (sp)+, d0/d1/d2/a0/a1/a2/a3/a4/a5/a6
+ rts
+
+
+_putchar:
+ move.l #1, -(sp)
+ pea (11,sp)
+ move.l #1, -(sp)
+ jsr (_write)
+ lea (12, sp), sp
+ rts
+.align 2
+
.sect .data
fmt: .asciz "%s, line %d: "
unknwn: .asciz "unknown file"
.sect .text
.fatal:
jsr (.trp)
- jmp (EXIT)
+ jmp (_exit)
.align 2
.sect .bss
.sect .text
+ESET=2
+
.inn: ! d0 bitnumber
! d1 setsize in bytes
! on exit: 0 or 1 in d0
.sect .data
.sect .bss
.sect .text
+EILLINS=18
! (on entry d0 contains the integer size in the descriptor)
.lar:
cmp.l #4, d0
! a1: base address
! d0: index
! d1: # bytes / element
- ! d2: save return address
! For address calculation; see comment in 'aar.s'.
- move.l (sp)+, d2 ! return address
+ move.l (sp)+, d1 ! return address
move.l (sp)+, a0 ! descriptor address
move.l (sp)+, d0 ! index
move.l (sp)+, a1 ! array base address
sub.l (a0), d0 ! relative index
+ move.l d1,-(sp)
move.l (8,a0), d1 ! # bytes / element
cmp.l #1, d1
bne 2f
- clr.l -(sp)
+ move.l (sp),a0
+ clr.l (sp)
move.b (a1,d0.l), (3,sp) ! one byte element
- bra 5f
+ jmp (a0)
2:
cmp.l #2, d1
bne 4f
- clr.l -(sp)
+ move.l (sp),a0
+ clr.l (sp)
move.w (a1,d0.l*2), (2,sp) ! two byte element
- bra 5f
+ jmp (a0)
4:
muls.l d1, d0
add.l d0, a1 ! address of 4n byte element
add.l d1, a1 ! because of predecrement
asr.l #2, d1
sub.l #1, d1
+ move.l (sp)+,a0
1:
move.l -(a1), -(sp)
dbf d1, 1b
-5:
- move.l d2,a0
jmp (a0)
.align 2
pea (fmt)
jsr (.diagnos)
add.l #8, sp
- jmp (EXIT)
+ jmp (_exit)
.sect .data
fmt: .asciz "system call %d not implemented\n"
.sect .rom
.sect .data
.sect .bss
+EILLINS=18
.sect .text
! (on entry d0 contains the integer size in the descriptor)
! a1: base address
! d0: index
! d1: # bytes / element
- ! d2: return address
! For address calculation; see comment in 'aar.s'.
! If the element size is a fraction of EM_WSIZE (4)
! the calculation is done by adding.
- move.l (sp)+, d2 ! return address
+ move.l (sp)+, d1 ! return address
move.l (sp)+, a0
move.l (sp)+, d0
move.l (sp)+, a1
+ move.l d1,-(sp) ! return address
sub.l (a0), d0
move.l (8,a0), d1 ! # bytes / element
cmp.l #1, d1
bne 2f
+ move.l (sp)+,a0
move.l (sp)+, d1
move.b d1, (a1,d0.l) ! store one byte element
- bra 5f
+ jmp (a0)
2:
cmp.l #2, d1
bne 4f
+ move.l (sp)+,a0
move.l (sp)+, d1
move.w d1, (a1,d0.l*2) ! store two byte element
- bra 5f
+ jmp (a0)
4: ! here: 4n byte element
muls.l d1, d0
add.l d0, a1 ! address of 4n byte element
asr.l #2, d1
sub.l #1, d1
+ move.l (sp)+,a0
1:
move.l (sp)+, (a1)+
dbf d1, 1b
-5:
- move.l d2,a0
jmp (a0)
.align 2
.sect .data
.sect .bss
.sect .text
+ESET=2
.set: ! d0 bitnumber
! d1 setsize in bytes
+ ! a1 saved d2
+ ! a0 return address
move.l (sp)+, a0
move.l d2, a1
.sect .rom
.sect .data
.sect .bss
+EHEAP=17
.sect .text
.strhp:
--- /dev/null
+acc -c.s -L -LIB -I../../../h trpstr.c
+sed s/_trpstr/.trpstr/g < trpstr.s > trpstr.ss
+mv trpstr.ss trpstr.s
add.l #4, sp
rts
9:
- pea (fmt)
+ jsr (.trpstr)
+ move.l d0,-(sp)
jsr (.diagnos)
lea (4, sp), sp
- jsr (__cleanup)
- jmp (EXIT)
-
-.sect .data
-fmt: .asciz "trap %d called\n"
+ jsr (_exit)
.align 2
--- /dev/null
+#include <em_abs.h>
+char *
+trpstr(d)
+{
+ switch(d)
+ {
+ case EARRAY: return "array bound error";
+ case ERANGE: return "range bound error";
+ case ESET: return "set bound error";
+ case EIOVFL: return "integer overflow";
+ case EFOVFL: return "floating overflow";
+ case EFUNFL: return "floating underflow";
+ case EIDIVZ: return "divide by 0";
+ case EFDIVZ: return "divide by 0.0";
+ case EIUND: return "undefined integer";
+ case EFUND: return "undefined real";
+ case ECONV: return "conversion error";
+ case ESTACK: return "stack overflow";
+ case EHEAP: return "heap overflow";
+ case EILLINS: return "illegal instruction";
+ case EODDZ: return "illegal size argument";
+ case ECASE: return "case error";
+ case EMEMFLT: return "addressing non-existent memory";
+ case EBADPTR: return "bad pointer used";
+ case EBADPC: return "program counter out of range";
+ case EBADMON: return "bad monitor call";
+ case EBADLIN:
+ case EBADGTO:
+ case EBADLAE:
+ default:
+ return "strange trap";
+ }
+ /*NOTREACHED*/
+}