misc/instructiontest.s (2/2)
1 2 movea.l 14(sp),a0 ;pc
moveq.l #$ffffffc0,d0
and.w (a0),d0 ;oc
cmp.w #$40c0,d0
beq 10f ;move-from-sr
movem.l (sp)+,d0-d1/a0
move.l old_privilege_instruction,-(sp)
rts
;move-from-sr
10: ori.w #$0200,(a0) ;modify move-from-sr to move-from-ccr
jbsr cache_flush
movem.l (sp)+,d0-d1/a0
rte
.data
.align 4
old_privilege_instruction:
.dc.l 0
;--------------------------------------------------------------------------------
;timerc
.text
.even
new_timerc_handler:
addq.l #1,timerc_counter
move.l old_timerc_handler,-(sp)
rts
.data
.align 4
old_timerc_handler:
.dc.l 0
timerc_counter:
.dc.l 0
;--------------------------------------------------------------------------------
;mnemonic
;<d0.l:test_number
;<a0.l:mnemonic
;>d0.l:0=skip,1=test
;?a0-a1
.text
.even
mnemonic_check:
movem.l a0-a2,-(sp)
lea.l test_flag,a2
adda.l d0,a2
tst.b (a2)
bne 2f ;already tested
lea.l mnemonic_buffer,a1
cmpi.l #'all'<<8,(a1)
beq 3f ;all
1: tst.b (a1)
beq 3f
cmpm.b (a0)+,(a1)+
beq 1b
2: moveq.l #0,d0 ;skip
bra 4f
3: st.b (a2)
move.b test_level,d0
cmp.b last_level,d0
beq @f
move.b d0,last_level
jbsr print_header
@@:
move.l timerc_counter,mnemonic_started
moveq.l #1,d0 ;test
4: movem.l (sp)+,a0-a2
rts
.bss
.align 4
mnemonic_buffer:
.ds.b 256+4
.align 4
mnemonic_started:
.ds.l 1
mnemonic_ended:
.ds.l 1
;--------------------------------------------------------------------------------
;test
.text
.even
test_start:
clr.l test_failed
clr.l test_tested
rts
;<d1.l:expected crc32
;<CRC32_REG.l:actual crc32
;?d0
.text
.even
test_check:
move.l timerc_counter,mnemonic_ended
movem.l d0-d1,-(sp)
addq.l #1,test_tested
move.l d1,d0 ;expected crc32
jbsr print_hex8
print ' '
move.l CRC32_REG,d0 ;actual crc32
jbsr print_hex8
cmp.l CRC32_REG,d1
bne 1f
print ' OK '
bra 2f
1: print ' ERROR '
addq.l #1,test_failed
2: move.l mnemonic_ended,d0
sub.l mnemonic_started,d0
moveq.l #2,d1
jbsr print_fix
print 's',13,10
movem.l (sp)+,d0-d1
rts
test_end:
movem.l d0-d4,-(sp)
move.l test_failed,d2
;<d2.lfailed
move.l test_tested,d3
;<d3.l:tested
move.l d3,d4
sub.l d2,d4
;<d4.l:passed
print 'tested:'
move.l d3,d0 ;tested
jbsr print_dec
tst.l d3
beq 38f ;no tests were performed
print ', passed:'
move.l d4,d0 ;passed
jbsr print_dec
print '('
mulu.w #10000,d0
divu.w d3,d0 ;10000*passed/tested
and.l #$0000ffff,d0
move.l #10000,d4
sub.w d0,d4 ;100-100*passed/tested
moveq.l #2,d1
jbsr print_fix
print '%), failed:'
move.l d2,d0 ;failed
jbsr print_dec
print '('
move.l d4,d0 ;100-100*passed/tested
jbsr print_fix
print '%)'
38:
jbsr print_crlf
move.l test_ended,d0
sub.l test_started,d0
moveq.l #2,d1
jbsr print_fix
print 's',13,10
movem.l (sp)+,d0-d4
rts
.bss
.align 4
test_failed:
.ds.l 1
test_tested:
.ds.l 1
test_started:
.ds.l 1
test_ended:
.ds.l 1
;--------------------------------------------------------------------------------
;ccr data
.data
.align 4
ccr_mono_data:
.dc.w 0,31
;sentry
.dc.w 0
.align 4
ccr_light_data:
.dc.w %00000,%11111,%00001,%11110,%00010,%11101,%00100,%11011,%01000,%10111,%10000,%01111
;sentry
.dc.w 0
.align 4
ccr_full_data:
.dc.w 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
;sentry
.dc.w 0
;--------------------------------------------------------------------------------
;bit field data
.data
.align 4
bf_offset_data:
.dc.l 0,1,7,8,9,15,16,17,23,24,25,31 ;zero must appear first
.dc.l 32,33,39,40,41,47,48,49,55,56,57,63
.dc.l -32,-31,-25,-24,-23,-17,-16,-15,-9,-8,-7,-1
;sentry
.dc.l 0
bf_width_data:
.dc.l 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
;sentry
.dc.l 0
;--------------------------------------------------------------------------------
;byte data
put_byte .macro x
.dc.l x
.dc.l .notb.(x)
.dc.l $ffffff00+(x)
.dc.l $ffffff00+.notb.(x)
.endm
.data
.align 4
byte_mono_data:
;no one
put_byte 0
;sentry
.dc.l 0
.align 4
byte_light_data:
;no one
put_byte 0
;one one
.irp i,0,1,7
put_byte 1<<i
.endm
;two ones
.irp i,0,1,7
.irp j,0,1,7
.if i>j
put_byte (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,7
.irp j,0,1,7
.if i>j+1
put_byte (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
.align 4
byte_medium_data:
;no one
put_byte 0
;one one
.irp i,0,1,2,4,6,7
put_byte 1<<i
.endm
;two ones
.irp i,0,1,2,4,6,7
.irp j,0,1,2,4,6,7
.if i>j
put_byte (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,2,4,6,7
.irp j,0,1,2,4,6,7
.if i>j+1
put_byte (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
.align 4
byte_heavy_data:
;no one
put_byte 0
;one one
.irp i,0,1,2,3,4,5,6,7
put_byte 1<<i
.endm
;two ones
.irp i,0,1,2,3,4,5,6,7
.irp j,0,1,2,3,4,5,6,7
.if i>j
put_byte (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,2,3,4,5,6,7
.irp j,0,1,2,3,4,5,6,7
.if i>j+1
put_byte (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
.align 4
byte_full_data:
.irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.irp j,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
put_byte (i<<4)+j
.endm
.endm
;sentry
.dc.l 0
;--------------------------------------------------------------------------------
;word data
put_word .macro x
.dc.l x
.dc.l .notw.(x)
.dc.l $ffff0000+(x)
.dc.l $ffff0000+.notw.(x)
.endm
.data
.align 4
word_mono_data:
;no one
put_word 0
;sentry
.dc.l 0
.align 4
word_light_data:
;no one
put_word 0
;one one
.irp i,0,1,7,8,9,15
put_word 1<<i
.endm
;two ones
.irp i,0,1,7,8,9,15
.irp j,0,1,7,8,9,15
.if i>j
put_word (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,7,8,9,15
.irp j,0,1,7,8,9,15
.if i>j+1
put_word (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
.align 4
word_medium_data:
;no one
put_word 0
;one one
.irp i,0,1,2,4,6,7,8,9,10,12,14,15
put_word 1<<i
.endm
;two ones
.irp i,0,1,2,4,6,7,8,9,10,12,14,15
.irp j,0,1,2,4,6,7,8,9,10,12,14,15
.if i>j
put_word (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,2,4,6,7,8,9,10,12,14,15
.irp j,0,1,2,4,6,7,8,9,10,12,14,15
.if i>j+1
put_word (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
.align 4
word_heavy_data:
;no one
put_word 0
;one one
.irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
put_word 1<<i
.endm
;two ones
.irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.irp j,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.if i>j
put_word (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.irp j,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.if i>j+1
put_word (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
;--------------------------------------------------------------------------------
;long data
put_long .macro x
.dc.l x
.dc.l .not.(x)
.endm
.data
.align 4
long_mono_data:
;no one
put_long 0
;sentry
.dc.l 0
.align 4
long_light_data:
;no one
put_long 0
;one one
.irp i,0,1,7,8,9,15,16,17,23,24,25,31
put_long 1<<i
.endm
;two ones
.irp i,0,1,7,8,9,15,16,17,23,24,25,31
.irp j,0,1,7,8,9,15,16,17,23,24,25,31
.if i>j
put_long (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,7,8,9,15,16,17,23,24,25,31
.irp j,0,1,7,8,9,15,16,17,23,24,25,31
.if i>j+1
put_long (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
.align 4
long_medium_data:
;no one
put_long 0
;one one
.irp i,0,1,2,4,6,7,8,9,10,12,14,15,16,17,18,20,22,23,24,25,26,28,30,31
put_long 1<<i
.endm
;two ones
.irp i,0,1,2,4,6,7,8,9,10,12,14,15,16,17,18,20,22,23,24,25,26,28,30,31
.irp j,0,1,2,4,6,7,8,9,10,12,14,15,16,17,18,20,22,23,24,25,26,28,30,31
.if i>j
put_long (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,2,4,6,7,8,9,10,12,14,15,16,17,18,20,22,23,24,25,26,28,30,31
.irp j,0,1,2,4,6,7,8,9,10,12,14,15,16,17,18,20,22,23,24,25,26,28,30,31
.if i>j+1
put_long (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
.align 4
long_heavy_data:
;no one
put_long 0
;one one
.irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
put_long 1<<i
.endm
;two ones
.irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
.irp j,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
.if i>j
put_long (1<<i)+(1<<j)
.endif
.endm
.endm
;three or more consecutive ones
.irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
.irp j,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
.if i>j+1
put_long (2<<i)-(1<<j)
.endif
.endm
.endm
;sentry
.dc.l 0
;--------------------------------------------------------------------------------
;quad data
put_quad .macro xh,xl
.dc.l xh,xl
.dc.l .not.(xh),.not.(xl)
.endm
.data
.align 4
quad_mono_data:
;no one
put_quad 0,0
;sentry
.dc.l 0,0
.align 4
quad_light_data:
;no one
put_quad 0,0
;one one
.irp i,0,1,7,8,9,15,16,17,23,24,25,31,32,33,39,40,41,47,48,49,55,56,57,63
.if i<32
put_quad 0,1<<i
.else
put_quad 1<<(i-32),0
.endif
.endm
;two ones
.irp i,0,1,7,8,9,15,16,17,23,24,25,31,32,33,39,40,41,47,48,49,55,56,57,63
.irp j,0,1,7,8,9,15,16,17,23,24,25,31,32,33,39,40,41,47,48,49,55,56,57,63
.if i>j
.if i<32
put_quad 0,(1<<i)+(1<<j)
.elif j<32
put_quad 1<<(i-32),1<<j
.else
put_quad (1<<(i-32))+(1<<(j-32)),0
.endif
.endif
.endm
.endm
;sentry
.dc.l 0,0
;--------------------------------------------------------------------------------
;sext data
put_sext .macro xh,xm,xl
.dc.l xh,xm,xl
.dc.l .not.(xh),.not.(xm),.not.(xl)
.endm
.data
.align 4
sext_mono_data:
;no one
put_sext 0,0,0
;sentry
.dc.l 0,0,0
.align 4
sext_light_data:
;no one
put_sext 0,0,0
;one one
.irp i,0,1,7,8,9,15,16,17,23,24,25,31,32,33,39,40,41,47,48,49,55,56,57,63,64,65,71,72,73,79,80,81,87,88,89,95
.if i<32
put_sext 0,0,1<<i
.elif i<64
put_sext 0,1<<(i-32),0
.else
put_sext 1<<(i-64),0,0
.endif
.endm
;sentry
.dc.l 0,0,0
;--------------------------------------------------------------------------------
;oct data
put_oct .macro x0,x1,x2,x3
.dc.l x0,x1,x2,x3
.dc.l .not.(x0),.not.(x1),.not.(x2),.not.(x3)
.endm
.data
.align 4
oct_mono_data:
;no one
put_oct 0,0,0,0
;sentry
.dc.l 0,0,0,0
.align 4
oct_light_data:
;no one
put_oct 0,0,0,0
;one one
.irp i,0,1,7,8,9,15,16,17,23,24,25,31,32,33,39,40,41,47,48,49,55,56,57,63,64,65,71,72,73,79,80,81,87,88,89,95,96,97,103,104,105,111,112,113,119,120,121,127
.if i<32
put_oct 0,0,0,1<<i
.elif i<64
put_oct 0,0,1<<(i-32),0
.elif i<96
put_oct 0,1<<(i-64),0,0
.else
put_oct 1<<(i-96),0,0,0
.endif
.endm
;sentry
.dc.l 0,0,0,0
.align 4
oct_medium_data:
;no one
put_oct 0,0,0,0
;one one
.irp i,0,1,2,4,6,7,8,9,10,12,14,15,16,17,18,20,22,23,24,25,26,28,30,31,32,33,34,36,38,39,40,41,42,44,46,47,48,49,50,52,54,55,56,57,58,60,62,63,64,65,66,68,70,71,72,73,74,76,78,79,80,81,82,84,86,87,88,89,90,92,94,95,96,97,98,100,102,103,104,105,106,108,110,111,112,113,114,116,118,119,120,121,122,124,126,127
.if i<32
put_oct 0,0,0,1<<i
.elif i<64
put_oct 0,0,1<<(i-32),0
.elif i<96
put_oct 0,1<<(i-64),0,0
.else
put_oct 1<<(i-96),0,0,0
.endif
.endm
;sentry
.dc.l 0,0,0,0
;--------------------------------------------------------------------------------
;mpu
.text
.even
mpu_check:
move.l mpu_number,d0
bmi @f
rts
@@: movem.l d1/a0-a1,-(sp)
;
clr.l -(sp)
DOS _SUPER
move.l d0,(sp)
;
move.w sr,-(sp) ;sr
ori.w #$0700,sr
move.l $002c.w,-(sp) ;line 1111 emulator
move.l $0010.w,-(sp) ;illegal instruction
lea.l 100f(pc),a1
move.l a1,$0010.w
move.l a1,$002c.w
movea.l sp,a1
;MC68000
;!VBR
moveq.l #0,d1
lea.l 99f(pc),a0
.cpu 68010
movec.l vbr,d0
.cpu 68000
;MC68010
;VBR && !scale factor
moveq.l #1,d1
moveq.l #1,d0
.cpu 68020
and.b (*-3,pc,d0.w*2),d0
.cpu 68010
beq 99f
;MC68020
;CALLM
moveq.l #2,d1
lea.l 29f(pc),a0
.cpu 68020
callm #0,21f(pc)
.cpu 68000
bra 99f
;module descriptor
21: .dc.l 0<<13|0<<24|0<<16 ;option=0,type=0,accesslevel=0
.dc.l 22f ;module entry pointer
.dc.l 0 ;module data area pointer
.dc.l 0
;module entry
22: .dc.w 15<<12 ;Rn=sp
.cpu 68020
rtm sp
.cpu 68000
29:
;MC68030
;!CALLM && CAAR
moveq.l #3,d1
lea.l 39f(pc),a0
.cpu 68030
movec.l caar,d0
.cpu 68000
bra 99f
39:
;MC68040
;MMUSR
moveq.l #4,d1
lea.l 49f(pc),a0
.cpu 68040
movec.l mmusr,d0
.cpu 68000
bra 99f
49:
;MC68060
;PCR
moveq.l #6,d1
lea.l 69f(pc),a0
.cpu 68060
movec.l pcr,d0
.cpu 68000
bra 99f
69:
;unknown
moveq.l #0,d1
;
99: move.l (sp)+,$0010.w ;illegal instruction
move.l (sp)+,$002c.w ;line 1111 emulator
move.w (sp)+,sr ;sr
;
DOS _SUPER
addq.l #4,sp
;
move.l d1,d0
movem.l (sp)+,d1/a0-a1
move.l d0,mpu_number
rts
100: movea.l a1,sp
jmp (a0)
;cache flush
; supervisor mode only
cache_flush:
move.l d0,-(sp)
jbsr mpu_check
subq.b #2,d0
bcs 9f
subq.b #4-2,d0
bcc 4f
;MC68020/MC68030
.cpu 68030
movec.l cacr,d0
or.w #$0808,d0
movec.l d0,cacr
and.w #$f7f7,d0
movec.l d0,cacr
.cpu 68000
bra 9f
;MC68040/MC68060
4: .cpu 68040
cpusha bc
.cpu 68000
9: move.l (sp)+,d0
rts
.data
.align 4
mpu_number:
.dc.l -1
;--------------------------------------------------------------------------------
;crc32
.if 0
.text
.even
crc32_test:
move.l d0,-(sp)
;crc32('A')=$d3d99e8b
jbsr crc32_reset
moveq.l #'A',d0
jbsr crc32_byte
jbsr crc32_print
jbsr print_crlf
;crc32('ABCD')=$db1720a5
jbsr crc32_reset
move.l #'ABCD',d0
jbsr crc32_long
jbsr crc32_print
jbsr print_crlf
move.l (sp)+,d0
rts
crc32_print:
move.l d0,-(sp)
move.l CRC32_REG,d0
jbsr print_hex8
move.l (sp)+,d0
rts
.endif
.text
.even
crc32_reset:
moveq.l #0,CRC32_REG
rts
;<d0.b:data
;<CRC32_REG.l:crc32
;>CRC32_REG.l:crc32
;?d0
.text
.even
crc32_byte:
move.l d0,-(sp)
not.l CRC32_REG
eor.b d0,CRC32_REG
moveq.l #0,d0
move.b CRC32_REG,d0
lsr.l #8,CRC32_REG
lsl.w #2,d0
move.l crc32_table(pc,d0.w),d0
eor.l d0,CRC32_REG
not.l CRC32_REG
move.l (sp)+,d0
rts
;<d0.w:data
;<CRC32_REG.l:crc32
;>CRC32_REG.l:crc32
.text
.even
crc32_word:
movem.l d0-d1,-(sp)
not.l CRC32_REG
moveq.l #-2,d1
1: moveq.l #0,d0
move.b 4(sp,d1.w),d0
eor.b CRC32_REG,d0
lsr.l #8,CRC32_REG
lsl.w #2,d0
move.l crc32_table(pc,d0.w),d0
eor.l d0,CRC32_REG
addq.w #1,d1
bne 1b
not.l CRC32_REG
movem.l (sp)+,d0-d1
rts
;<d0.l:data
;<CRC32_REG.l:crc32
;>CRC32_REG.l:crc32
.text
.even
crc32_long:
movem.l d0-d1,-(sp)
not.l CRC32_REG
moveq.l #-4,d1
1: moveq.l #0,d0
move.b 4(sp,d1.w),d0
eor.b CRC32_REG,d0
lsr.l #8,CRC32_REG
lsl.w #2,d0
move.l crc32_table(pc,d0.w),d0
eor.l d0,CRC32_REG
addq.w #1,d1
bne 1b
not.l CRC32_REG
movem.l (sp)+,d0-d1
rts
.text
.align 4
crc32_table:
.dc.l $00000000,$77073096,$ee0e612c,$990951ba,$076dc419,$706af48f,$e963a535,$9e6495a3
.dc.l $0edb8832,$79dcb8a4,$e0d5e91e,$97d2d988,$09b64c2b,$7eb17cbd,$e7b82d07,$90bf1d91
.dc.l $1db71064,$6ab020f2,$f3b97148,$84be41de,$1adad47d,$6ddde4eb,$f4d4b551,$83d385c7
.dc.l $136c9856,$646ba8c0,$fd62f97a,$8a65c9ec,$14015c4f,$63066cd9,$fa0f3d63,$8d080df5
.dc.l $3b6e20c8,$4c69105e,$d56041e4,$a2677172,$3c03e4d1,$4b04d447,$d20d85fd,$a50ab56b
.dc.l $35b5a8fa,$42b2986c,$dbbbc9d6,$acbcf940,$32d86ce3,$45df5c75,$dcd60dcf,$abd13d59
.dc.l $26d930ac,$51de003a,$c8d75180,$bfd06116,$21b4f4b5,$56b3c423,$cfba9599,$b8bda50f
.dc.l $2802b89e,$5f058808,$c60cd9b2,$b10be924,$2f6f7c87,$58684c11,$c1611dab,$b6662d3d
.dc.l $76dc4190,$01db7106,$98d220bc,$efd5102a,$71b18589,$06b6b51f,$9fbfe4a5,$e8b8d433
.dc.l $7807c9a2,$0f00f934,$9609a88e,$e10e9818,$7f6a0dbb,$086d3d2d,$91646c97,$e6635c01
.dc.l $6b6b51f4,$1c6c6162,$856530d8,$f262004e,$6c0695ed,$1b01a57b,$8208f4c1,$f50fc457
.dc.l $65b0d9c6,$12b7e950,$8bbeb8ea,$fcb9887c,$62dd1ddf,$15da2d49,$8cd37cf3,$fbd44c65
.dc.l $4db26158,$3ab551ce,$a3bc0074,$d4bb30e2,$4adfa541,$3dd895d7,$a4d1c46d,$d3d6f4fb
.dc.l $4369e96a,$346ed9fc,$ad678846,$da60b8d0,$44042d73,$33031de5,$aa0a4c5f,$dd0d7cc9
.dc.l $5005713c,$270241aa,$be0b1010,$c90c2086,$5768b525,$206f85b3,$b966d409,$ce61e49f
.dc.l $5edef90e,$29d9c998,$b0d09822,$c7d7a8b4,$59b33d17,$2eb40d81,$b7bd5c3b,$c0ba6cad
.dc.l $edb88320,$9abfb3b6,$03b6e20c,$74b1d29a,$ead54739,$9dd277af,$04db2615,$73dc1683
.dc.l $e3630b12,$94643b84,$0d6d6a3e,$7a6a5aa8,$e40ecf0b,$9309ff9d,$0a00ae27,$7d079eb1
.dc.l $f00f9344,$8708a3d2,$1e01f268,$6906c2fe,$f762575d,$806567cb,$196c3671,$6e6b06e7
.dc.l $fed41b76,$89d32be0,$10da7a5a,$67dd4acc,$f9b9df6f,$8ebeeff9,$17b7be43,$60b08ed5
.dc.l $d6d6a3e8,$a1d1937e,$38d8c2c4,$4fdff252,$d1bb67f1,$a6bc5767,$3fb506dd,$48b2364b
.dc.l $d80d2bda,$af0a1b4c,$36034af6,$41047a60,$df60efc3,$a867df55,$316e8eef,$4669be79
.dc.l $cb61b38c,$bc66831a,$256fd2a0,$5268e236,$cc0c7795,$bb0b4703,$220216b9,$5505262f
.dc.l $c5ba3bbe,$b2bd0b28,$2bb45a92,$5cb36a04,$c2d7ffa7,$b5d0cf31,$2cd99e8b,$5bdeae1d
.dc.l $9b64c2b0,$ec63f226,$756aa39c,$026d930a,$9c0906a9,$eb0e363f,$72076785,$05005713
.dc.l $95bf4a82,$e2b87a14,$7bb12bae,$0cb61b38,$92d28e9b,$e5d5be0d,$7cdcefb7,$0bdbdf21
.dc.l $86d3d2d4,$f1d4e242,$68ddb3f8,$1fda836e,$81be16cd,$f6b9265b,$6fb077e1,$18b74777
.dc.l $88085ae6,$ff0f6a70,$66063bca,$11010b5c,$8f659eff,$f862ae69,$616bffd3,$166ccf45
.dc.l $a00ae278,$d70dd2ee,$4e048354,$3903b3c2,$a7672661,$d06016f7,$4969474d,$3e6e77db
.dc.l $aed16a4a,$d9d65adc,$40df0b66,$37d83bf0,$a9bcae53,$debb9ec5,$47b2cf7f,$30b5ffe9
.dc.l $bdbdf21c,$cabac28a,$53b39330,$24b4a3a6,$bad03605,$cdd70693,$54de5729,$23d967bf
.dc.l $b3667a2e,$c4614ab8,$5d681b02,$2a6f2b94,$b40bbe37,$c30c8ea1,$5a05df1b,$2d02ef8d
;--------------------------------------------------------------------------------
;print decimal number
;<d0.l:number
.text
.even
print_dec:
movem.l d0-d2/a0-a1,-(sp)
lea.l -12(sp),sp
movea.l sp,a0
tst.l d0
bne 1f
move.b #'0',(a0)+
bra 5f
1:
lea.l base_ten(pc),a1
2:
move.l (a1)+,d1
cmp.l d1,d0
blo 2b
3:
moveq.l #'0'-1,d2
4:
addq.b #1,d2
sub.l d1,d0
bcc 4b
add.l d1,d0
move.b d2,(a0)+
move.l (a1)+,d1
bne 3b
5:
suba.l sp,a0
move.l a0,-(sp)
pea.l 4(sp)
move.w #1,-(sp)
DOS _WRITE
lea.l 10+12(sp),sp
movem.l (sp)+,d0-d2/a0-a1
rts
;--------------------------------------------------------------------------------
;print fixed point decimal number
;<d0.l:fixed point decimal number * 10^d1
;<d1.b:number of digits after decimal point (>=1)
.text
.even
print_fix:
movem.l d0-d4/a0-a1,-(sp)
moveq.l #0,d3
move.b d1,d3
;<d3.l:number of digits after decimal point (>=1)
move.l d3,d4
addq.w #3,d4
and.w #-4,d4 ;round up to multiples of four
add.w #12,d4 ;12 bytes for integer part and decimal point
;<d4.l:buffer size
suba.l d4,sp
;<sp.l:buffer
movea.l sp,a0
tst.l d0
bne 20f
;zero
move.b #'0',(a0)+
move.b #'.',(a0)+
move.w d3,d2 ;number of digits after decimal point (>=1)
bra 12f
11:
move.b #'0',(a0)+
12:
dbra d2,11b
bra 80f ;print
;non-zero
20:
lea.l base_ten(pc),a1
;zero suppression
21:
move.l (a1)+,d1
cmp.l d1,d0
blo 21b
;convert to decimal number
22:
moveq.l #'0'-1,d2
23:
addq.b #1,d2
sub.l d1,d0
bcc 23b
add.l d1,d0
move.b d2,(a0)+
move.l (a1)+,d1
bne 22b
;
move.l a0,d2
sub.l sp,d2
;<d2.l:number of digits
cmp.w d3,d2
bls 40f
;number of digits > number of digits after decimal point
;insert '.'
move.w d3,d2 ;number of digits after decimal point (>=1)
movea.l a0,a1
addq.l #1,a0
bra 32f
31:
move.b -(a1),1(a1)
32:
dbra d2,31b
move.b #'.',(a1)
bra 80f
40:
;number of digits after decimal point >= number of digits
;insert '0.00...'
move.w d3,d0 ;number of digits after decimal point (>=1)
sub.w d2,d0 ;number of zeros after decimal point (>=0)
movea.l a0,a1
lea.l 2(a0,d0.w),a0
bra 42f
41:
move.b -(a1),2(a1,d0.w)
42:
dbra d2,41b
movea.l sp,a1
move.b #'0',(a1)+
move.b #'.',(a1)+
bra 44f
43:
move.b #'0',(a1)+
44:
dbra d0,43b
;print
80:
suba.l sp,a0
move.l a0,-(sp) ;length
pea.l 4(sp) ;buffer
move.w #1,-(sp) ;stdout
DOS _WRITE
lea.l 10(sp),sp
adda.l d4,sp
movem.l (sp)+,d0-d4/a0-a1
rts
.align 4
base_ten:
.dc.l 1000000000
.dc.l 100000000
.dc.l 10000000
.dc.l 1000000
.dc.l 100000
.dc.l 10000
.dc.l 1000
.dc.l 100
.dc.l 10
.dc.l 1
.dc.l 0
;--------------------------------------------------------------------------------
;print hexadecimal number
;<d0.l:number
.text
.even
print_hex8:
movem.l d0-d2/a0,-(sp)
lea.l -10(sp),sp
movea.l sp,a0
move.b #'$',(a0)+
moveq.l #8-1,d2
2:
rol.l #4,d0
moveq.l #15,d1
and.w d0,d1
move.b 10f(pc,d1.w),(a0)+
dbra d2,2b
pea.l 1+8.w
pea.l 4(sp)
move.w #1,-(sp)
DOS _WRITE
lea.l 10+10(sp),sp
movem.l (sp)+,d0-d2/a0
rts
10:
.dc.b '0123456789abcdef'
;--------------------------------------------------------------------------------
;print crlf
.text
.even
print_crlf:
move.l d0,-(sp)
pea.l 2.w
pea.l 10f(pc)
move.w #1,-(sp)
DOS _WRITE
lea.l 10(sp),sp
move.l (sp)+,d0
rts
10:
.dc.b 13,10
;--------------------------------------------------------------------------------
;print character
;<4(sp).w:character
.text
.even
putchar_by_write:
move.l d0,-(sp)
pea.l 1.w
pea.l 12+1(sp)
move.w #1,-(sp)
DOS _WRITE
lea.l 10(sp),sp
move.l (sp)+,d0
rts
;--------------------------------------------------------------------------------
;print string
;<4(sp).l:string
.text
.even
print_by_write:
movem.l d0/a0-a1,-(sp)
movea.l 16(sp),a1
movea.l a1,a0
@@:
tst.b (a1)+
bne @b
subq.l #1,a1
suba.l a0,a1
movem.l a0-a1,-(sp)
move.w #1,-(sp)
DOS _WRITE
lea.l 10(sp),sp
movem.l (sp)+,d0/a0-a1
rts
;--------------------------------------------------------------------------------
;end
.end main