English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 22 June 2021, 00:33   #321
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Quote:
Originally Posted by Bruce Abbott View Post
This version is the same speed as the earlier one I tested (8.9 seconds without printing, 10 seconds with printing) but dramatically smaller at 700 bytes vs. 804. Well done!

But I see my work isn't done. I will test your latest version tonight.

That may be so, but it is interesting to note that printing 3000 digits takes ~1.1 seconds on my machine, which is only 11% of the total execution time. On a slower machine it should be an even smaller percentage because a large part of that time is taken up rendering to ChipRAM, which is proportionally slower on a faster machine.
Could you check on Amiga with 68000 CPU too (divu.w vs sub.w version)? If no speed difference then i will change access from PR000N to PR0000. 6 bytes shortest code.
Don_Adan is offline  
Old 22 June 2021, 10:20   #322
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Gained 2 bytes in time routine.
Code:
OldOpenLibrary = -408
CloseLibrary = -414
Output = -60
Input = -54
Write = -48
Read = -42
Forbid = -132
Permit = -138
AddIntServer = -168
RemIntServer = -174
VBlankFrequency = 530
INTB_VERTB = 5     ;for vblank interrupt
NT_INTERRUPT = 2   ;node type

;N = 7*D/2 ;D digits, e.g., N = 350 for 100 digits

start
         lea libname(pc),a1         ;open the dos library
         move.l 4.W,a5
         move.l a5,a6
         jsr OldOpenLibrary(a6)
         move.l d0,a6
         jsr Output(a6)          ;get stdout
         lea cout(PC),A4
         move.l d0,(A4)            ;cout
         move.w	#((65536-(ra-start))/(7<<2))<<2,D7	; d7.w=maxn (moved here)
         moveq #-4,D4
;call Write(stdout,buff,size)
         moveq #msg1-cout,D2 ; must be checked if in moveq range, the longest text can be moved at end
         moveq #msg4-msg1,d3
         bsr.b .write
.l20 
         moveq #msg4-cout,D2
         moveq #msg5-msg4,d3
         bsr.b .write
         move.w d7,d5
         bsr.w PR0000
         moveq #msg5-cout,D2
         moveq #msg3-msg5,d3
         bsr.b .write
         bsr.w getnum
         cmp.w d7,d5
         bhi.b .l20
         move.w d5,d1
         beq.b .l20
         addq.w #3,d5
         and.w D4,d5
         cmp.b #10,(a0)
         bne.b .l21
         move.w d5,d6
         cmp.w d1,d5
         beq.b .l7
.l21
         bsr.w PR0000
         moveq #msg3-cout,D2
         moveq #msg2-msg3,d3
         bsr.b .write

.l7 
         mulu.w #7,d6          ;kv = d6
         lsr.l #2,D6               ; /4
         move.l d6,d7
         lea ra(pc),a3

         exg a5,a6
         jsr Forbid(a6)
         moveq #INTB_VERTB,d0
         lea VBlankServer(pc),a1
         jsr AddIntServer(a6)
         exg a5,a6
         ;move.w #$4000,$dff096    ;DMA off
 
         move.l #2000*65537,d0
         move.l a3,a0
.fill    move.l d0,(a0)+
         subq.l #1,D7
         bne.b .fill

         move.l D7,-(SP)    ; cv
         lea 10000.W,A2
         moveq #4,D3
         moveq #buf-cout,D2
         add.l  A4,D2 ; buf

.l0      moveq #0,D5       ;d <- 0
         move.l d6,d4     ;i <- kv, i <- i*2
         lsl.l #2,D4           ; *4
         adda.l d4,a3
         subq.l #1,d4     ;b <- 2*i-1
         move.l A2,D1
         bra.b .l4

.write
         move.l (A4),D1 ; cout
         add.l A4,D2
         jmp Write(a6)

.longdiv
         swap d0
         move.w d0,d7
         divu.w d4,d7
         swap d7
         move.w d7,d0
         swap d0
         divu.w d4,d0

         move.w d0,d7
         exg d0,d7
         clr.w d7
         swap d7
         move.w d7,(a3)     ;r[i] <- d%b
         bra.b .enddiv

.l2
         sub.l d0,d5
         sub.l d7,d5
         lsr.l #1,d5
.l4
         move -(a3),d0      ; r[i]
         mulu.w d1,d0       ;r[i]*10000
         add.l d0,d5       ;d += r[i]*10000
         move.l d5,d0
         divu.w d4,d0
         bvs.s .longdiv

         move.w d0,d7
         clr.w d0
         swap d0
         move.w d0,(a3)     ;r[i] <- d%b
.enddiv
         subq.l #2,d4    ;i <- i - 1
         bcc.b .l2       ;the main loop
         divu.w d1,d5      ;removed with MULU optimization
 
         add.w (SP),D5 ; cv
         move.l D5,(SP) ; cv
         bsr.w PR000N

         subq.l #7,d6   ;kv
         bne.b .l0
         addq.l #4,SP ;  restore stack


         move.l time(pc),d5
         ;move.w #$c000,$dff096    ;DMA on
         exg a5,a6
         moveq #INTB_VERTB,d0
         lea VBlankServer(pc),a1
         jsr RemIntServer(a6)
         jsr Permit(a6)
         exg a5,a6

         cmp.b #50,VBlankFrequency(a5)
         beq.b .l8

         lsl.l #2,D5       ;  480 Hz
         add.l time(PC),d5 ;  600 Hz
         divu.w #6,d5      ;  100 Hz
         swap d5
         lsr.w #3,d5
         swap d5
         negx.l d5
         neg.l d5

.l8   
         moveq #1+3+1,D3
         lea 12(A4),A3
         moveq #10,D1
         move.b D1,-(A3)  ; newline

         moveq #$30,D0 
;     D7 highword is already cleared
     divu.w d1,d5
     bvc.b .div32no

     swap d5
     move.w d5,d7
     divu.w d1,d7
     swap d7
     move d7,d5
     swap d5
     divu.w d1,d5
.div32no
     move.w d5,d7
     swap d5
        add.b D0,D5
         move.b d5,-(a3)
         divu.w d1,d7
         swap d7
       add.b D0,D7
         move.b d7,-(a3)
         clr.w d7
         swap d7
         move.b #'.',-(a3)      ; dot
.l12     tst.w d7
         beq .l11

         addq.l #1,D3
         divu.w d1,d7
         swap d7
       add.b D0,D7
         move.b d7,-(a3)
         clr.w d7
         swap d7
         bra .l12

.l11
         move.b #32,-(A3)           ; space
         move.l (A4),D1            ; cout
         move.l A3,D2
         jsr Write(a6) 

         move.l a6,a1
         move.l a5,a6
         jmp CloseLibrary(a6)

PR0000     ;prints d5, uses a0,a1(scratch),d0,d1,d2,d3
      moveq #4,D3
      moveq #buf-cout,D2
      add.l  A4,D2 ; buf
PR000N
        move.w	#$0100,a0
	move.l	#$2f3a2f2f,d0
	move.w	#1000,d1
.b1000	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b1000
	add.w	d1,d5

	moveq	#100,d1
.b100	addq.b	#1,d0
	sub.w	d1,d5
	bcc.b	.b100
	add.w	d1,d5

	swap	d0
	moveq	#10,d1
.b10	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b10
	add.b	d5,d0

        move.l D0,buf-cout(A4) ; buf
        move.l (A4),D1    ; cout
        jmp Write(A6) ;call Write(stdout,buff,size)

rasteri
      addq.l #2,(a1)
;If you set your interrupt to priority 10 or higher then a0 must point at $dff000 on exit
      moveq #0,d0  ; must set Z flag on exit!
      rts

VBlankServer:
      dc.l  0,0                   ;ln_Succ,ln_Pred
      dc.b  NT_INTERRUPT,0        ;ln_Type,ln_Pri
      dc.l  0                     ;ln_Name
      dc.l  time,rasteri          ;is_Data,is_Code


 cnop 0,4

 cout dc.l 0
 buf ds.b 4
 time dc.l 0

; Overwritten code/data start here. 
ra
libname  dc.b "dos.library",0
msg1  dc.b 'number pi calculator v13',10
msg4 dc.b 'number of digits (up to '
msg5 dc.b ')? '
msg3 dc.b ' digits will be printed',10
msg2
      even
getnum
        jsr Input(a6)          ;get stdin
        moveq #msg1-cout,D2
        add.l A4,D2
        move.l d0,d1
        moveq #5,d3     ;+ newline
        jsr Read(a6)
 
        move.l	d2,a0
	moveq	#0,d5
.loop	subq.w	#1,d0
	beq.b	.done
	move.w	#256-'0',d6
	add.b	(a0)+,d6
	cmp.w	#9,d6
	bhi.b	.error
	mulu.w	#10,d5
	add.w	d6,d5
	bra.b	.loop
.error	moveq	#0,d5
.done	rts

Buffy
     ds.b 65536-(Buffy-start)

Last edited by Don_Adan; 22 June 2021 at 11:28.
Don_Adan is offline  
Old 22 June 2021, 19:58   #323
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
Reimplemented the time calc&print code, it's 32 bytes shorter (and the whole thing is now under 600 bytes):
Code:
...
	jsr	Permit(a6)
	exg	a5,a6


	move.b	VBlankFrequency(a5),d6	; d6.l is 0
	move.l	d6,d0
	add.w	d0,d0
	divu.w	d0,d5			; d5 = seconds
	move.l	d5,d1
	swap	d1
	mulu.w	#100,d1
	add.l	d1,d6			; round up (+0.5)
	divu.w	d0,d6			; d6 = 1/100ths

	move.l	(a4)+,d1		; output
	move.l	a4,d2			; buffer

	move.b	#' ',(a4)+

	moveq	#0,d4			; skip leading zeroes
	move.w	#10000,d7
	bsr.b	SPrintTime

	move.b	#'.',(a4)+

	moveq	#'0',d4			; print leading zeroes
	move.w	d6,d5
	moveq	#10,d7
	bsr.b	SPrintTime

	move.b	#10,(a4)+		; newline

	move.l	a4,d3
	sub.l	d2,d3
	jsr	Write(a6)

	move.l	a6,a1
	move.l	a5,a6
	jmp	CloseLibrary(a6)		; END OF PROGRAM

SPrintTime	; d5=value, a4=buffer
.Next	ext.l	d5
	divu.w	d7,d5
	cmp.b	d4,d5
	beq.b	.LeadZero
	moveq	#'0',d4
	add.b	d4,d5
	move.b	d5,(a4)+
.LeadZero
	swap	d5
	divu.w	#10,d7
	bne.b	.Next
	rts


PR0000     ;prints d5, uses a0,a1(scratch),d0,d1,d2,d3
...
a/b is offline  
Old 22 June 2021, 21:40   #324
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Ok, big thanks. Perhaps
move.w #10000,d7
can be replaced with
move.l A2,D7
And we can use moveq #10,D0 to replace

move.b #10,(a4)+ ; newline

with
move.b D0,(a4)+ ; newline

and

divu.w #10,d7

with
divu.w D0,d7

What do you think?

BTW.I forget that D6 is cleared, then old time calc routine can be 2 bytes shortest too
Don_Adan is offline  
Old 22 June 2021, 22:04   #325
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
Yup, that would work. -2*2 bytes.
a/b is offline  
Old 23 June 2021, 00:45   #326
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Reimplemented time calc and print code from a/b.
Code:
OldOpenLibrary = -408
CloseLibrary = -414
Output = -60
Input = -54
Write = -48
Read = -42
Forbid = -132
Permit = -138
AddIntServer = -168
RemIntServer = -174
VBlankFrequency = 530
INTB_VERTB = 5     ;for vblank interrupt
NT_INTERRUPT = 2   ;node type

;N = 7*D/2 ;D digits, e.g., N = 350 for 100 digits

start
         lea libname(pc),a1         ;open the dos library
         move.l 4.W,a5
         move.l a5,a6
         jsr OldOpenLibrary(a6)
         move.l d0,a6
         jsr Output(a6)          ;get stdout
         lea cout(PC),A4
         move.l d0,(A4)            ;cout
         move.w	#((65536-(ra-start))/(7<<2))<<2,D7	; d7.w=maxn (moved here)
         moveq #-4,D4
;call Write(stdout,buff,size)
         moveq #msg1-cout,D2 ; must be checked if in moveq range, the longest text can be moved at end
         moveq #msg4-msg1,d3
         bsr.b .write
.l20 
         moveq #msg4-cout,D2
         moveq #msg5-msg4,d3
         bsr.b .write
         move.w d7,d5
         bsr.w PR0000
         moveq #msg5-cout,D2
         moveq #msg3-msg5,d3
         bsr.b .write
         bsr.w getnum
         cmp.w d7,d5
         bhi.b .l20
         move.w d5,d1
         beq.b .l20
         addq.w #3,d5
         and.w D4,d5
         cmp.b #10,(a0)
         bne.b .l21
         move.w d5,d6
         cmp.w d1,d5
         beq.b .l7
.l21
         bsr.w PR0000
         moveq #msg3-cout,D2
         moveq #msg2-msg3,d3
         bsr.b .write

.l7 
         mulu.w #7,d6          ;kv = d6
         lsr.l #2,D6               ; /4
         move.l d6,d7
         lea ra(pc),a3

         exg a5,a6
         jsr Forbid(a6)
         moveq #INTB_VERTB,d0
         lea VBlankServer(pc),a1
         jsr AddIntServer(a6)
         exg a5,a6
         ;move.w #$4000,$dff096    ;DMA off
 
         move.l #2000*65537,d0
         move.l a3,a0
.fill    move.l d0,(a0)+
         subq.l #1,D7
         bne.b .fill

         move.l D7,-(SP)    ; cv
         lea 10000.W,A2
         moveq #4,D3
         moveq #buf-cout,D2
         add.l  A4,D2 ; buf

.l0      moveq #0,D5       ;d <- 0
         move.l d6,d4     ;i <- kv, i <- i*2
         lsl.l #2,D4           ; *4
         adda.l d4,a3
         subq.l #1,d4     ;b <- 2*i-1
         move.l A2,D1
         bra.b .l4

.write
         move.l (A4),D1 ; cout
         add.l A4,D2
         jmp Write(a6)

.longdiv
         swap d0
         move.w d0,d7
         divu.w d4,d7
         swap d7
         move.w d7,d0
         swap d0
         divu.w d4,d0

         move.w d0,d7
         exg d0,d7
         clr.w d7
         swap d7
         move.w d7,(a3)     ;r[i] <- d%b
         bra.b .enddiv

.l2
         sub.l d0,d5
         sub.l d7,d5
         lsr.l #1,d5
.l4
         move -(a3),d0      ; r[i]
         mulu.w d1,d0       ;r[i]*10000
         add.l d0,d5       ;d += r[i]*10000
         move.l d5,d0
         divu.w d4,d0
         bvs.s .longdiv

         move.w d0,d7
         clr.w d0
         swap d0
         move.w d0,(a3)     ;r[i] <- d%b
.enddiv
         subq.l #2,d4    ;i <- i - 1
         bcc.b .l2       ;the main loop
         divu.w d1,d5      ;removed with MULU optimization
 
         add.w (SP),D5 ; cv
         move.l D5,(SP) ; cv
         bsr.w PR000N

         subq.l #7,d6   ;kv
         bne.b .l0
         addq.l #4,SP ;  restore stack


         move.l time(pc),d5
         ;move.w #$c000,$dff096    ;DMA on
         exg a5,a6
         moveq #INTB_VERTB,d0
         lea VBlankServer(pc),a1
         jsr RemIntServer(a6)
         jsr Permit(a6)
         exg a5,a6

	move.b	VBlankFrequency(a5),d6	; d6.l is 0
	move.l	d6,d0
	add.w	d0,d0
	divu.w	d0,d5			; d5 = seconds
	move.l	d5,d1
	swap	d1
	mulu.w	#100,d1
	add.l	d1,d6			; round up (+0.5)
	divu.w	d0,d6			; d6 = 1/100ths
        moveq   #10,D0
	move.l	(a4)+,d1		; output
	move.l	a4,d2			; buffer

	move.b	#' ',(a4)+

	moveq	#0,d4			; skip leading zeroes
        move.l  A2,D7	                ; 10000
	bsr.b	SPrintTime

	move.b	#'.',(a4)+

	moveq	#'0',d4			; print leading zeroes
	move.w	d6,d5
	moveq	#10,d7
	bsr.b	SPrintTime

	move.b	d0,(a4)+		; newline

	move.l	a4,d3
	sub.l	d2,d3
	jsr	Write(a6)

	move.l	a6,a1
	move.l	a5,a6
	jmp	CloseLibrary(a6)		; END OF PROGRAM

SPrintTime	; d5=value, a4=buffer
.Next	ext.l	d5
	divu.w	d7,d5
	cmp.b	d4,d5
	beq.b	.LeadZero
	moveq	#'0',d4
	add.b	d4,d5
	move.b	d5,(a4)+
.LeadZero
	swap	d5
	divu.w	d0,d7
	bne.b	.Next
	rts

PR0000     ;prints d5, uses a0,a1(scratch),d0,d1,d2,d3
      moveq #4,D3
      moveq #buf-cout,D2
      add.l  A4,D2 ; buf
PR000N
        move.w	#$0100,a0
	move.l	#$2f3a2f2f,d0
	move.w	#1000,d1
.b1000	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b1000
	add.w	d1,d5

	moveq	#100,d1
.b100	addq.b	#1,d0
	sub.w	d1,d5
	bcc.b	.b100
	add.w	d1,d5

	swap	d0
	moveq	#10,d1
.b10	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b10
	add.b	d5,d0

        move.l D0,buf-cout(A4) ; buf
        move.l (A4),D1    ; cout
        jmp Write(A6) ;call Write(stdout,buff,size)

rasteri
      addq.l #2,(a1)
;If you set your interrupt to priority 10 or higher then a0 must point at $dff000 on exit
      moveq #0,d0  ; must set Z flag on exit!
      rts

VBlankServer:
      dc.l  0,0                   ;ln_Succ,ln_Pred
      dc.b  NT_INTERRUPT,0        ;ln_Type,ln_Pri
      dc.l  0                     ;ln_Name
      dc.l  time,rasteri          ;is_Data,is_Code


 cnop 0,4

 cout dc.l 0
 buf ds.b 4
 time dc.l 0

; Overwritten code/data start here. 
ra
libname  dc.b "dos.library",0
msg1  dc.b 'number pi calculator v13',10
msg4 dc.b 'number of digits (up to '
msg5 dc.b ')? '
msg3 dc.b ' digits will be printed',10
msg2
      even
getnum
        jsr Input(a6)          ;get stdin
        moveq #msg1-cout,D2
        add.l A4,D2
        move.l d0,d1
        moveq #5,d3     ;+ newline
        jsr Read(a6)
 
        move.l	d2,a0
	moveq	#0,d5
.loop	subq.w	#1,d0
	beq.b	.done
	move.w	#256-'0',d6
	add.b	(a0)+,d6
	cmp.w	#9,d6
	bhi.b	.error
	mulu.w	#10,d5
	add.w	d6,d5
	bra.b	.loop
.error	moveq	#0,d5
.done	rts

Buffy
     ds.b 65536-(Buffy-start)

Last edited by Don_Adan; 23 June 2021 at 00:56.
Don_Adan is offline  
Old 23 June 2021, 02:08   #327
Bruce Abbott
Registered User
 
Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 2,581
Quote:
Originally Posted by Don_Adan View Post
Could you check on Amiga with 68000 CPU too (divu.w vs sub.w version)? If no speed difference then i will change access from PR000N to PR0000. 6 bytes shortest code.
Both the PR000N and PR0000 versions took 163 seconds on my A500 when printing to a full-size CLI window.

Your post #327 took 9.9 seconds to execute on my A1200, with a file size of 652 bytes. This is 2 bytes shorter than litwr's 'pi-ibmpc.com'!
Bruce Abbott is offline  
Old 23 June 2021, 02:10   #328
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
Yeah, I'll reach 1000 posts just from this thread alone .
Code:
;         bsr.w PR000N
         bsr.b PR000N		; keep your pr000n close (i did not say that)
-2 bytes
a/b is offline  
Old 23 June 2021, 02:40   #329
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Quote:
Originally Posted by Bruce Abbott View Post
Both the PR000N and PR0000 versions took 163 seconds on my A500 when printing to a full-size CLI window.

Your post #327 took 9.9 seconds to execute on my A1200, with a file size of 652 bytes. This is 2 bytes shorter than litwr's 'pi-ibmpc.com'!
Ok, thanks, then final (?) version after a few minutes will be available. Exe size will be shortest.
Don_Adan is offline  
Old 23 June 2021, 02:55   #330
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Fully PC relative version. But i dont remember if using move.l A0,-(A0) is safe for 68040/68060. Then maybe it must be changed.

Code:
OldOpenLibrary = -408
CloseLibrary = -414
Output = -60
Input = -54
Write = -48
Read = -42
Forbid = -132
Permit = -138
AddIntServer = -168
RemIntServer = -174
VBlankFrequency = 530
INTB_VERTB = 5     ;for vblank interrupt
NT_INTERRUPT = 2   ;node type

;N = 7*D/2 ;D digits, e.g., N = 350 for 100 digits

start
         lea libname(pc),a1         ;open the dos library
         move.l 4.W,a5
         move.l a5,a6
         jsr OldOpenLibrary(a6)
         move.l d0,a6
         jsr Output(a6)          ;get stdout
         lea cout(PC),A4
         move.l d0,(A4)            ;cout
         move.w	#((65536-(ra-start))/(7<<2))<<2,D7	; d7.w=maxn (moved here)
         moveq #-4,D4
;call Write(stdout,buff,size)
         moveq #msg1-cout,D2 ; must be checked if in moveq range, the longest text can be moved at end
         moveq #msg4-msg1,d3
         bsr.b .write
.l20 
         moveq #msg4-cout,D2
         moveq #msg5-msg4,d3
         bsr.b .write
         move.w d7,d5
         bsr.w PR0000
         moveq #msg5-cout,D2
         moveq #msg3-msg5,d3
         bsr.b .write
         bsr.w getnum
         cmp.w d7,d5
         bhi.b .l20
         move.w d5,d1
         beq.b .l20
         addq.w #3,d5
         and.w D4,d5
         move.w d5,d6
         cmp.b #10,(a0)
         bne.b .l21
         cmp.w d1,d5
         beq.b .l7
.l21
         bsr.w PR0000
         moveq #msg3-cout,D2
         moveq #msg2-msg3,d3
         bsr.b .write

.l7 
         mulu.w #7,d6          ;kv = d6
         lsr.l #2,D6               ; /4
         move.l d6,d7
         lea ra(pc),a3

         lea rasteri(PC),A0
         move.l A0,-(A0)
         move.l A4,-(A0)
         addq.l #time-cout,(A0)
         exg a5,a6
         jsr Forbid(a6)
         moveq #INTB_VERTB,d0
         lea VBlankServer(pc),a1
         jsr AddIntServer(a6)
         exg a5,a6
 
         move.l #2000*65537,d0
         move.l a3,a0
.fill    move.l d0,(a0)+
         subq.l #1,D7
         bne.b .fill

         move.l D7,-(SP)    ; cv
         lea 10000.W,A2

.l0      moveq #0,D5       ;d <- 0
         move.l d6,d4     ;i <- kv, i <- i*2
         lsl.l #2,D4           ; *4
         adda.l d4,a3
         subq.l #1,d4     ;b <- 2*i-1
         move.l A2,D1
         bra.b .l4

.write
         move.l (A4),D1 ; cout
         add.l A4,D2
         jmp Write(a6)

.longdiv
         swap d0
         move.w d0,d7
         divu.w d4,d7
         swap d7
         move.w d7,d0
         swap d0
         divu.w d4,d0

         move.w d0,d7
         exg d0,d7
         clr.w d7
         swap d7
         move.w d7,(a3)     ;r[i] <- d%b
         bra.b .enddiv

.l2
         sub.l d0,d5
         sub.l d7,d5
         lsr.l #1,d5
.l4
         move.w -(a3),d0      ; r[i]
         mulu.w d1,d0       ;r[i]*10000
         add.l d0,d5       ;d += r[i]*10000
         move.l d5,d0
         divu.w d4,d0
         bvs.s .longdiv

         move.w d0,d7
         clr.w d0
         swap d0
         move.w d0,(a3)     ;r[i] <- d%b
.enddiv
         subq.l #2,d4    ;i <- i - 1
         bcc.b .l2       ;the main loop
         divu.w d1,d5
 
         add.w (SP),D5 ; cv
         move.l D5,(SP) ; cv
         bsr.b PR0000
         subq.l #7,d6   ;kv
         bne.b .l0
         addq.l #4,SP ;  restore stack


         move.l time(pc),d5
         exg a5,a6
         moveq #INTB_VERTB,d0
         lea VBlankServer(pc),a1
         jsr RemIntServer(a6)
         jsr Permit(a6)
         exg a5,a6

	move.b	VBlankFrequency(a5),d6	; d6.l is 0
	move.l	d6,d0
	add.w	d0,d0
	divu.w	d0,d5			; d5 = seconds
	move.l	d5,d1
	swap	d1
	mulu.w	#100,d1
	add.l	d1,d6			; round up (+0.5)
	divu.w	d0,d6			; d6 = 1/100ths
        moveq   #10,D0
	move.l	(a4)+,d1		; output
	move.l	a4,d2			; buffer

	move.b	#' ',(a4)+

	moveq	#0,d4			; skip leading zeroes
        move.l  A2,D7	                ; 10000
	bsr.b	SPrintTime

	move.b	#'.',(a4)+

	moveq	#'0',d4			; print leading zeroes
	move.w	d6,d5
	moveq	#10,d7
	bsr.b	SPrintTime

	move.b	d0,(a4)+		; newline

	move.l	a4,d3
	sub.l	d2,d3
	jsr	Write(a6)

	move.l	a6,a1
	move.l	a5,a6
	jmp	CloseLibrary(a6)		; END OF PROGRAM

SPrintTime	; d5=value, a4=buffer
.Next	ext.l	d5
	divu.w	d7,d5
	cmp.b	d4,d5
	beq.b	.LeadZero
	moveq	#'0',d4
	add.b	d4,d5
	move.b	d5,(a4)+
.LeadZero
	swap	d5
	divu.w	d0,d7
	bne.b	.Next
	rts

PR0000     ;prints d5, uses a0,a1(scratch),d0,d1,d2,d3
      moveq #4,D3
      moveq #buf-cout,D2
      add.l  A4,D2 ; buf
        move.w	#$0100,a0
	move.l	#$2f3a2f2f,d0
	move.w	#1000,d1
.b1000	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b1000
	add.w	d1,d5

	moveq	#100,d1
.b100	addq.b	#1,d0
	sub.w	d1,d5
	bcc.b	.b100
	add.w	d1,d5

	swap	d0
	moveq	#10,d1
.b10	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b10
	add.b	d5,d0

        move.l D0,buf-cout(A4) ; buf
        move.l (A4),D1    ; cout
        jmp Write(A6) ;call Write(stdout,buff,size)

VBlankServer:
      dc.l  0,0                   ;ln_Succ,ln_Pred
      dc.b  NT_INTERRUPT,0        ;ln_Type,ln_Pri
      dc.l  0                     ;ln_Name
      dc.l  0,0          ;is_Data,is_Code

rasteri
      addq.l #2,(a1)
;If you set your interrupt to priority 10 or higher then a0 must point at $dff000 on exit
      moveq #0,d0  ; must set Z flag on exit!
      rts
 cnop 0,4

 cout dc.l 0
 buf ds.b 4
 time dc.l 0

; Overwritten code/data start here. 
ra
libname  dc.b "dos.library",0
msg1  dc.b 'number pi calculator v13',10
msg4 dc.b 'number of digits (up to '
msg5 dc.b ')? '
msg3 dc.b ' digits will be printed',10
msg2
      even
getnum
        jsr Input(a6)          ;get stdin
        moveq #msg1-cout,D2
        add.l A4,D2
        move.l d0,d1
        moveq #5,d3     ;+ newline
        jsr Read(a6)
 
        move.l	d2,a0
	moveq	#0,d5
.loop	subq.w	#1,d0
	beq.b	.done
	move.w	#256-'0',d6
	add.b	(a0)+,d6
	cmp.w	#9,d6
	bhi.b	.error
	mulu.w	#10,d5
	add.w	d6,d5
	bra.b	.loop
.error	moveq	#0,d5
.done	rts

Buffy
     ds.b 65536-(Buffy-start)

Last edited by Don_Adan; 23 June 2021 at 04:59.
Don_Adan is offline  
Old 23 June 2021, 04:18   #331
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
There's a bug, persisting through several versions, if you enter eg. 111111111 digits it will print out how many digits will actually be computed and it won't initialize d6=kv properly.
Fix: move.w d5,d6 should be moved 2 lines up (should be before cmp.w #10,(a0) + bne.b .l21).
a/b is offline  
Old 23 June 2021, 05:00   #332
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Quote:
Originally Posted by a/b View Post
There's a bug, persisting through several versions, if you enter eg. 111111111 digits it will print out how many digits will actually be computed and it won't initialize d6=kv properly.
Fix: move.w d5,d6 should be moved 2 lines up (should be before cmp.w #10,(a0) + bne.b .l21).
Ok, fixed. thanks.
Don_Adan is offline  
Old 23 June 2021, 23:43   #333
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Because im not sure if move.l A0,-(A0) is safe for 68040/68060. Here is version without this command, maybe a few bytes shortest.

Code:
OldOpenLibrary = -408
CloseLibrary = -414
Output = -60
Input = -54
Write = -48
Read = -42
Forbid = -132
Permit = -138
AddIntServer = -168
RemIntServer = -174
VBlankFrequency = 530
INTB_VERTB = 5     ;for vblank interrupt
NT_INTERRUPT = 2   ;node type

;N = 7*D/2 ;D digits, e.g., N = 350 for 100 digits

start
         lea libname(pc),a1         ;open the dos library
         move.l 4.W,a5
         move.l a5,a6
         jsr OldOpenLibrary(a6)
         move.l d0,a6
         jsr Output(a6)          ;get stdout
         lea cout(PC),A4
         move.l d0,(A4)            ;cout

         lea rasteri(PC),A0
         move.l A0,-(SP)      ; is_Code
         move.l A4,-(SP)
         addq.l #time-cout,(SP) ; is_Data
         clr.l -(SP)
         move.w #$200,-(SP)
         clr.l -(SP)
         clr.l -(SP)
         move.w	#((65536-(ra-start))/(7<<2))<<2,D7	; d7.w=maxn (moved here)
         moveq #-4,D4
;call Write(stdout,buff,size)
         moveq #msg1-cout,D2 ; must be checked if in moveq range, the longest text can be moved at end
         moveq #msg4-msg1,d3
         bsr.b .write
.l20 
         moveq #msg4-cout,D2
         moveq #msg5-msg4,d3
         bsr.b .write
         move.w d7,d5
         bsr.w PR0000
         moveq #msg5-cout,D2
         moveq #msg3-msg5,d3
         bsr.b .write
         bsr.w getnum
         cmp.w d7,d5
         bhi.b .l20
         move.w d5,d1
         beq.b .l20
         addq.w #3,d5
         and.w D4,d5
         move.w d5,d6
         cmp.b #10,(a0)
         bne.b .l21
         cmp.w d1,d5
         beq.b .l7
.l21
         bsr.w PR0000
         moveq #msg3-cout,D2
         moveq #msg2-msg3,d3
         bsr.b .write

.l7 
         mulu.w #7,d6          ;kv = d6
         lsr.l #2,D6               ; /4
         move.l d6,d7
         lea ra(pc),a3

         exg a5,a6
         jsr Forbid(a6)
         moveq #INTB_VERTB,d0
;         lea VBlankServer(pc),a1
         move.l SP,A1
         jsr AddIntServer(a6)
         exg a5,a6
 
         move.l #2000*65537,d0
         move.l a3,a0
.fill    move.l d0,(a0)+
         subq.l #1,D7
         bne.b .fill

         move.l D7,-(SP)    ; cv
         lea 10000.W,A2

.l0      moveq #0,D5       ;d <- 0
         move.l d6,d4     ;i <- kv, i <- i*2
         lsl.l #2,D4           ; *4
         adda.l d4,a3
         subq.l #1,d4     ;b <- 2*i-1
         move.l A2,D1
         bra.b .l4

.write
         move.l (A4),D1 ; cout
         add.l A4,D2
         jmp Write(a6)

.longdiv
         swap d0
         move.w d0,d7
         divu.w d4,d7
         swap d7
         move.w d7,d0
         swap d0
         divu.w d4,d0

         move.w d0,d7
         exg d0,d7
         clr.w d7
         swap d7
         move.w d7,(a3)     ;r[i] <- d%b
         bra.b .enddiv

.l2
         sub.l d0,d5
         sub.l d7,d5
         lsr.l #1,d5
.l4
         move.w -(a3),d0      ; r[i]
         mulu.w d1,d0       ;r[i]*10000
         add.l d0,d5       ;d += r[i]*10000
         move.l d5,d0
         divu.w d4,d0
         bvs.s .longdiv

         move.w d0,d7
         clr.w d0
         swap d0
         move.w d0,(a3)     ;r[i] <- d%b
.enddiv
         subq.l #2,d4    ;i <- i - 1
         bcc.b .l2       ;the main loop
         divu.w d1,d5
 
         add.w (SP),D5 ; cv
         move.l D5,(SP) ; cv
         bsr.b PR0000
         subq.l #7,d6   ;kv
         bne.b .l0
         addq.l #4,SP ;  restore stack


         move.l time(pc),d5
         exg a5,a6
         moveq #INTB_VERTB,d0
;         lea VBlankServer(pc),a1
         move.l SP,A1
         jsr RemIntServer(a6)
         jsr Permit(a6)
         exg a5,a6

        lea     22(SP),SP                ; restore stack
	move.b	VBlankFrequency(a5),d6	; d6.l is 0
	move.l	d6,d0
	add.w	d0,d0
	divu.w	d0,d5			; d5 = seconds
	move.l	d5,d1
	swap	d1
	mulu.w	#100,d1
	add.l	d1,d6			; round up (+0.5)
	divu.w	d0,d6			; d6 = 1/100ths
        moveq   #10,D0
	move.l	(a4)+,d1		; output
	move.l	a4,d2			; buffer

	move.b	#' ',(a4)+

	moveq	#0,d4			; skip leading zeroes
        move.l  A2,D7	                ; 10000
	bsr.b	SPrintTime

	move.b	#'.',(a4)+

	moveq	#'0',d4			; print leading zeroes
	move.w	d6,d5
	moveq	#10,d7
	bsr.b	SPrintTime

	move.b	d0,(a4)+		; newline

	move.l	a4,d3
	sub.l	d2,d3
	jsr	Write(a6)

	move.l	a6,a1
	move.l	a5,a6
	jmp	CloseLibrary(a6)		; END OF PROGRAM

SPrintTime	; d5=value, a4=buffer
.Next	ext.l	d5
	divu.w	d7,d5
	cmp.b	d4,d5
	beq.b	.LeadZero
	moveq	#'0',d4
	add.b	d4,d5
	move.b	d5,(a4)+
.LeadZero
	swap	d5
	divu.w	d0,d7
	bne.b	.Next
	rts

PR0000     ;prints d5, uses a0,a1(scratch),d0,d1,d2,d3
      moveq #4,D3
      moveq #buf-cout,D2
      add.l  A4,D2 ; buf
        move.w	#$0100,a0
	move.l	#$2f3a2f2f,d0
	move.w	#1000,d1
.b1000	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b1000
	add.w	d1,d5

	moveq	#100,d1
.b100	addq.b	#1,d0
	sub.w	d1,d5
	bcc.b	.b100
	add.w	d1,d5

	swap	d0
	moveq	#10,d1
.b10	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b10
	add.b	d5,d0

        move.l D0,buf-cout(A4) ; buf
        move.l (A4),D1    ; cout
        jmp Write(A6) ;call Write(stdout,buff,size)

;VBlankServer:
;      dc.l  0,0                   ;ln_Succ,ln_Pred
;      dc.b  NT_INTERRUPT,0        ;ln_Type,ln_Pri
;      dc.l  0                     ;ln_Name
;      dc.l  0,0          ;is_Data,is_Code

rasteri
      addq.l #2,(a1)
;If you set your interrupt to priority 10 or higher then a0 must point at $dff000 on exit
      moveq #0,d0  ; must set Z flag on exit!
      rts
 cnop 0,4

 cout dc.l 0
 buf ds.b 4
 time dc.l 0

; Overwritten code/data start here. 
ra
libname  dc.b "dos.library",0
msg1  dc.b 'number pi calculator v13',10
msg4 dc.b 'number of digits (up to '
msg5 dc.b ')? '
msg3 dc.b ' digits will be printed',10
msg2
      even
getnum
        jsr Input(a6)          ;get stdin
        moveq #msg1-cout,D2
        add.l A4,D2
        move.l d0,d1
        moveq #5,d3     ;+ newline
        jsr Read(a6)
 
        move.l	d2,a0
	moveq	#0,d5
.loop	subq.w	#1,d0
	beq.b	.done
	move.w	#256-'0',d6
	add.b	(a0)+,d6
	cmp.w	#9,d6
	bhi.b	.error
	mulu.w	#10,d5
	add.w	d6,d5
	bra.b	.loop
.error	moveq	#0,d5
.done	rts

Buffy
     ds.b 65536-(Buffy-start)
Don_Adan is offline  
Old 24 June 2021, 00:33   #334
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
It's safe, of course (this is basic EA stuff). I did my calcs on pentium and it's 100.00000324243% safe.
a/b is offline  
Old 24 June 2021, 01:39   #335
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Quote:
Originally Posted by a/b View Post
It's safe, of course (this is basic EA stuff). I did my calcs on pentium and it's 100.00000324243% safe.
I heard that A0-4 is stored, not A0. But it was many years ago, maybe i remember something wrong. Anyway new version is perhaps shortest, and i still have a few ideas for made this version shortest about 10 bytes?
Don_Adan is offline  
Old 24 June 2021, 14:47   #336
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
ln_Succ/ln_Pred are set by exec when the node is added to interrupt list, they don't have to be initialized manually:
Code:
         clr.l -(SP)				; ln_Name
;         move.w #$200,-(SP)
;         clr.l -(SP)
;         clr.l -(SP)
         move.w #NT_INTERRUPT<<8+0,-(SP)	; ln_Type, ln_Pri
         subq.l #2*4,SP				; ln_Succ, ln_Pred
-2 bytes...
a/b is offline  
Old 24 June 2021, 23:08   #337
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
This is perhaps final version, if no bugs. Thanks to a/b for help.
Edit, 2 more bytes gained.
Code:
OldOpenLibrary = -408
CloseLibrary = -414
Output = -60
Input = -54
Write = -48
Read = -42
Forbid = -132
Permit = -138
AddIntServer = -168
RemIntServer = -174
VBlankFrequency = 530
INTB_VERTB = 5     ;for vblank interrupt
NT_INTERRUPT = 2   ;node type

;N = 7*D/2 ;D digits, e.g., N = 350 for 100 digits

start
         lea libname(pc),a1         ;open the dos library
         move.l 4.W,a5
         move.l a5,a6
         jsr OldOpenLibrary(a6)
         move.l d0,a6
         jsr Output(a6)          ;get stdout
         lea time(PC),A4
         lea rasteri(PC),A0
         move.l A0,-(SP)      ; is_Code
         move.l A4,-(SP)      ; is_Data
         clr.l -(SP)          ; ln_Name
         move.w #NT_INTERRUPT<<8+0,-(SP)	; ln_Type, ln_Pri
         subq.l #2*4,SP				; ln_Succ, ln_Pred
         move.l d0,-(A4)            ;cout
         move.w	#((65536-(ra-start))/(7<<2))<<2,D7	; d7.w=maxn (moved here)
         moveq #10,D4
;call Write(stdout,buff,size)
         moveq #msg1-cout,D2 ; must be checked if in moveq range, the longest text can be moved at end
         moveq #msg4-msg1,d3
         bsr.b .write
.l20 
         moveq #msg4-cout,D2
         moveq #msg5-msg4,d3
         bsr.b .write
         move.w d7,d5
         bsr.w PR0000
         moveq #msg5-cout,D2
         moveq #msg3-msg5,d3
         bsr.b .write
         bsr.w getnum
         cmp.w d7,d5
         bhi.b .l20
         move.w d5,d1
         beq.b .l20
         addq.w #3,d5
         and.w #$fffc,d5
         move.w d5,d6
         cmp.b (a0),D4    ; 10
         bne.b .l21
         cmp.w d1,d5
         beq.b .l7
.l21
         bsr.w PR0000
         moveq #msg3-cout,D2
         moveq #msg2-msg3,d3
         bsr.b .write

.l7 
         mulu.w #7,d6          ;kv = d6
         lsr.l #2,D6               ; /4
         move.l d6,d7
         lea ra(pc),a3

         exg a5,a6
         jsr Forbid(a6)
         moveq #INTB_VERTB,d0
;         lea VBlankServer(pc),a1
         move.l SP,A1
         jsr AddIntServer(a6)
         exg a5,a6
 
         move.l #2000*65537,d0
         move.l a3,a0
.fill    move.l d0,(a0)+
         subq.l #1,D7
         bne.b .fill

         move.l D7,-(SP)    ; cv
         lea 10000.W,A2

.l0      moveq #0,D5       ;d <- 0
         move.l d6,d4     ;i <- kv, i <- i*2
         lsl.l #2,D4           ; *4
         adda.l d4,a3
         subq.l #1,d4     ;b <- 2*i-1
         move.l A2,D1
         bra.b .l4

.write
         move.l (A4),D1 ; cout
         add.l A4,D2
         jmp Write(a6)

.longdiv
         swap d0
         move.w d0,d7
         divu.w d4,d7
         swap d7
         move.w d7,d0
         swap d0
         divu.w d4,d0

         move.w d0,d7
         exg d0,d7
         clr.w d7
         swap d7
         move.w d7,(a3)     ;r[i] <- d%b
         bra.b .enddiv

.l2
         sub.l d0,d5
         sub.l d7,d5
         lsr.l #1,d5
.l4
         move.w -(a3),d0      ; r[i]
         mulu.w d1,d0       ;r[i]*10000
         add.l d0,d5       ;d += r[i]*10000
         move.l d5,d0
         divu.w d4,d0
         bvs.s .longdiv

         move.w d0,d7
         clr.w d0
         swap d0
         move.w d0,(a3)     ;r[i] <- d%b
.enddiv
         subq.l #2,d4    ;i <- i - 1
         bcc.b .l2       ;the main loop
         divu.w d1,d5
 
         add.w (SP),D5 ; cv
         move.l D5,(SP) ; cv
         bsr.b PR0000
         subq.l #7,d6   ;kv
         bne.b .l0
         addq.l #4,SP ;  restore stack


;         move.l time(pc),d5
         exg a5,a6
         moveq #INTB_VERTB,d0
;         lea VBlankServer(pc),a1
         move.l SP,A1
         jsr RemIntServer(a6)
         jsr Permit(a6)
 
        movem.l (A4),D1/D5        ; last use of cout and time
        exg a5,a6
        lea     22(SP),SP                ; restore stack
	move.b	VBlankFrequency(a5),d6	; d6.l is 0
	move.l	d6,d0
	add.w	d0,d0
	divu.w	d0,d5			; d5 = seconds
	move.l	d5,d2
	swap	d2
	mulu.w	#100,d2
	add.l	d2,d6			; round up (+0.5)
	divu.w	d0,d6			; d6 = 1/100ths
        moveq   #10,D0
;	move.l	(a4)+,d1		; output
	move.l	a4,d2			; buffer

	move.b	#' ',(a4)+

	moveq	#0,d4			; skip leading zeroes
        move.l  A2,D7	                ; 10000
	bsr.b	SPrintTime

	move.b	#'.',(a4)+

	moveq	#'0',d4			; print leading zeroes
	move.w	d6,d5
	moveq	#10,d7
	bsr.b	SPrintTime

	move.b	d0,(a4)+		; newline

	move.l	a4,d3
	sub.l	d2,d3
	jsr	Write(a6)

	move.l	a6,a1
	move.l	a5,a6
	jmp	CloseLibrary(a6)		; END OF PROGRAM

SPrintTime	; d5=value, a4=buffer
.Next	ext.l	d5
	divu.w	d7,d5
	cmp.b	d4,d5
	beq.b	.LeadZero
	moveq	#'0',d4
	add.b	d4,d5
	move.b	d5,(a4)+
.LeadZero
	swap	d5
	divu.w	d0,d7
	bne.b	.Next
	rts

PR0000     ;prints d5, uses a0,a1(scratch),d0,d1,d2,d3
      moveq #4,D3
      moveq #buf-cout,D2
        move.w	#$0100,a0
	move.l	#$2f3a2f2f,d0
	move.w	#1000,d1
.b1000	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b1000
	add.w	d1,d5

	moveq	#100,d1
.b100	addq.b	#1,d0
	sub.w	d1,d5
	bcc.b	.b100
	add.w	d1,d5

	swap	d0
	moveq	#10,d1
.b10	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b10
	add.b	d5,d0

        move.l D0,buf-cout(A4) ; buf
        bra.w .write
;        move.l (A4),D1    ; cout
;        add.l  A4,D2 ; buf
;        jmp Write(A6) ;call Write(stdout,buff,size)

;VBlankServer:
;      dc.l  0,0                   ;ln_Succ,ln_Pred
;      dc.b  NT_INTERRUPT,0        ;ln_Type,ln_Pri
;      dc.l  0                     ;ln_Name
;      dc.l  0,0          ;is_Data,is_Code

rasteri
      addq.l #2,(a1)
;If you set your interrupt to priority 10 or higher then a0 must point at $dff000 on exit
      moveq #0,d0  ; must set Z flag on exit!
      rts
 cnop 0,4

 cout dc.l 0
 time dc.l 0
 buf ds.b 4

; Overwritten code/data start here. 
ra
libname  dc.b "dos.library",0
msg1  dc.b 'number pi calculator v13',10
msg4 dc.b 'number of digits (up to '
msg5 dc.b ')? '
msg3 dc.b ' digits will be printed',10
msg2
      even
getnum
        jsr Input(a6)          ;get stdin
        moveq #msg1-cout,D2
        add.l A4,D2
        move.l d0,d1
        moveq #5,d3     ;+ newline
        jsr Read(a6)
 
        move.l	d2,a0
	moveq	#0,d5
.loop	subq.w	#1,d0
	beq.b	.done
	move.w	#256-'0',d6
	add.b	(a0)+,d6
	cmp.w	#9,d6
	bhi.b	.error
	mulu.w	d4,d5    ; *10
	add.w	d6,d5
	bra.b	.loop
.error	moveq	#0,d5
.done	rts

Buffy
     ds.b 65536-(Buffy-start)

Last edited by Don_Adan; 25 June 2021 at 12:23. Reason: fixed illegal command
Don_Adan is offline  
Old 25 June 2021, 03:06   #338
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Optional version, maybe better?
Code:
OldOpenLibrary = -408
CloseLibrary = -414
Output = -60
Input = -54
Write = -48
Read = -42
Forbid = -132
Permit = -138
AddIntServer = -168
RemIntServer = -174
VBlankFrequency = 530
INTB_VERTB = 5     ;for vblank interrupt
NT_INTERRUPT = 2   ;node type

;N = 7*D/2 ;D digits, e.g., N = 350 for 100 digits

start
         lea libname(pc),a1         ;open the dos library
         move.l 4.W,a5
         move.l a5,a6
         jsr OldOpenLibrary(a6)
         move.l d0,a6
         jsr Output(a6)          ;get stdout
         lea time(PC),A4
         lea rasteri(PC),A0
         move.l A0,-(SP)      ; is_Code
         move.l A4,-(SP)      ; is_Data
         clr.l -(SP)          ; ln_Name
         move.w #NT_INTERRUPT<<8+0,-(SP)	; ln_Type, ln_Pri
         subq.l #2*4,SP				; ln_Succ, ln_Pred
         move.l d0,-(A4)            ;cout
         move.w	#((65536-(ra-start))/(7<<2))<<2,D7	; d7.w=maxn (moved here)
         moveq #10,D4
;call Write(stdout,buff,size)
         moveq #msg1-cout,D2 ; must be checked if in moveq range, the longest text can be moved at end
         moveq #msg4-msg1,d3
         bsr .write
.l20 
         bsr.w ngetnum
         cmp.w d7,d5
         bhi.b .l20
         move.w d5,d1
         beq.b .l20
         addq.w #3,d5
         and.w #$fffc,d5
         move.w d5,d6
         cmp.b (a0),D4    ; 10
         bne.b .l21
         cmp.w d1,d5
         beq.b .l7
.l21
         bsr.w PR0000
         moveq #msg3-cout,D2
         moveq #msg2-msg3,d3
         bsr .write

.l7 
         mulu.w #7,d6          ;kv = d6
         lsr.l #2,D6               ; /4
         move.l d6,d7
         lea ra(pc),a3

         exg a5,a6
         jsr Forbid(a6)
         moveq #INTB_VERTB,d0
;         lea VBlankServer(pc),a1
         move.l SP,A1
         jsr AddIntServer(a6)
         exg a5,a6
 
         move.l #2000*65537,d0
         move.l a3,a0
.fill    move.l d0,(a0)+
         subq.l #1,D7
         bne.b .fill

         move.l D7,-(SP)    ; cv
         lea 10000.W,A2

.l0      moveq #0,D5       ;d <- 0
         move.l d6,d4     ;i <- kv, i <- i*2
         lsl.l #2,D4           ; *4
         adda.l d4,a3
         subq.l #1,d4     ;b <- 2*i-1
         move.l A2,D1
         bra.b .l4

.longdiv
         swap d0
         move.w d0,d7
         divu.w d4,d7
         swap d7
         move.w d7,d0
         swap d0
         divu.w d4,d0

         move.w d0,d7
         exg d0,d7
         clr.w d7
         swap d7
         move.w d7,(a3)     ;r[i] <- d%b
         bra.b .enddiv

.l2
         sub.l d0,d5
         sub.l d7,d5
         lsr.l #1,d5
.l4
         move.w -(a3),d0      ; r[i]
         mulu.w d1,d0       ;r[i]*10000
         add.l d0,d5       ;d += r[i]*10000
         move.l d5,d0
         divu.w d4,d0
         bvs.s .longdiv

         move.w d0,d7
         clr.w d0
         swap d0
         move.w d0,(a3)     ;r[i] <- d%b
.enddiv
         subq.l #2,d4    ;i <- i - 1
         bcc.b .l2       ;the main loop
         divu.w d1,d5
 
         add.w (SP),D5 ; cv
         move.l D5,(SP) ; cv
         bsr.b PR0000
         subq.l #7,d6   ;kv
         bne.b .l0
         addq.l #4,SP ;  restore stack


;         move.l time(pc),d5
         exg a5,a6
         moveq #INTB_VERTB,d0
;         lea VBlankServer(pc),a1
         move.l SP,A1
         jsr RemIntServer(a6)
         jsr Permit(a6)
 
        movem.l (A4),D1/D5        ; last use of cout and time
        exg a5,a6
        lea     22(SP),SP                ; restore stack
	move.b	VBlankFrequency(a5),d6	; d6.l is 0
	move.l	d6,d0
	add.w	d0,d0
	divu.w	d0,d5			; d5 = seconds
	move.l	d5,d2
	swap	d2
	mulu.w	#100,d2
	add.l	d2,d6			; round up (+0.5)
	divu.w	d0,d6			; d6 = 1/100ths
        moveq   #10,D0
;	move.l	(a4)+,d1		; output
	move.l	a4,d2			; buffer

	move.b	#' ',(a4)+

	moveq	#0,d4			; skip leading zeroes
        move.l  A2,D7	                ; 10000
	bsr.b	SPrintTime

	move.b	#'.',(a4)+

	moveq	#'0',d4			; print leading zeroes
	move.w	d6,d5
	moveq	#10,d7
	bsr.b	SPrintTime

	move.b	d0,(a4)+		; newline

	move.l	a4,d3
	sub.l	d2,d3
	jsr	Write(a6)

	move.l	a6,a1
	move.l	a5,a6
	jmp	CloseLibrary(a6)		; END OF PROGRAM

SPrintTime	; d5=value, a4=buffer
.Next	ext.l	d5
	divu.w	d7,d5
	cmp.b	d4,d5
	beq.b	.LeadZero
	moveq	#'0',d4
	add.b	d4,d5
	move.b	d5,(a4)+
.LeadZero
	swap	d5
	divu.w	d0,d7
	bne.b	.Next
	rts

PR0000     ;prints d5, uses a0,a1(scratch),d0,d1,d2,d3
      moveq #4,D3
      moveq #buf-cout,D2
        move.w	#$0100,a0
	move.l	#$2f3a2f2f,d0
	move.w	#1000,d1
.b1000	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b1000
	add.w	d1,d5

	moveq	#100,d1
.b100	addq.b	#1,d0
	sub.w	d1,d5
	bcc.b	.b100
	add.w	d1,d5

	swap	d0
	moveq	#10,d1
.b10	add.w	a0,d0
	sub.w	d1,d5
	bcc.b	.b10
	add.b	d5,d0

        move.l D0,buf-cout(A4) ; buf
.write
        move.l (A4),D1    ; cout
        add.l  A4,D2 ; buf
        jmp Write(A6) ;call Write(stdout,buff,size)

;VBlankServer:
;      dc.l  0,0                   ;ln_Succ,ln_Pred
;      dc.b  NT_INTERRUPT,0        ;ln_Type,ln_Pri
;      dc.l  0                     ;ln_Name
;      dc.l  0,0          ;is_Data,is_Code

rasteri
      addq.l #2,(a1)
;If you set your interrupt to priority 10 or higher then a0 must point at $dff000 on exit
      moveq #0,d0  ; must set Z flag on exit!
      rts
 cnop 0,4

 cout dc.l 0
 time dc.l 0
 buf ds.b 4

; Overwritten code/data start here. 
ra
msg1  dc.b 'number pi calculator v13',10
msg4 dc.b 'number of digits (up to '
msg5 dc.b ')? '
msg3 dc.b ' digits will be printed',10
msg2
      even
ngetnum
         moveq #msg4-cout,D2
         moveq #msg5-msg4,d3
         bsr.b .write
         move.w d7,d5
         bsr.b PR0000
         moveq #msg5-cout,D2
         moveq #msg3-msg5,d3
         bsr.b .write
        jsr Input(a6)          ;get stdin
        moveq #msg1-cout,D2
        add.l A4,D2
        move.l d0,d1
        moveq #5,d3     ;+ newline
        jsr Read(a6)
 
        move.l	d2,a0
	moveq	#0,d5
.loop	subq.w	#1,d0
	beq.b	.done
	move.w	#256-'0',d6
	add.b	(a0)+,d6
	cmp.w	#9,d6
	bhi.b	.error
	mulu.w	d4,d5    ; *10
	add.w	d6,d5
	bra.b	.loop
.error	moveq	#0,d5
.done	rts
libname  dc.b "dos.library",0
Buffy
     ds.b 65536-(Buffy-start)

Last edited by Don_Adan; 25 June 2021 at 12:24. Reason: fixed illegal command
Don_Adan is offline  
Old 25 June 2021, 09:46   #339
Bruce Abbott
Registered User
 
Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 2,581
Quote:
Originally Posted by Don_Adan View Post
Optional version, maybe better?
Both this one and the one in post #338 are 608 bytes on disk, but #338 is slightly faster at 9.51 seconds vs. 9.57 (average over 5 runs).

Now we are well below litwr's 'pi-pc386.com' code size of 623 bytes, and faster than the theoretical 40MHz 386 at 10.4 seconds. Only Amiga makes it possible!

BTW I have changed my test setup slightly, so times will now be a bit quicker. I realized that the shell window can be made small and then enlarged after running to show all the text, and I changed the WorkBench screen to 4 colors because that is the Amiga's 'standard' resolution.
Bruce Abbott is offline  
Old 25 June 2021, 09:52   #340
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
Quote:
Originally Posted by Bruce Abbott View Post
Both this one and the one in post #338 are 608 bytes on disk, but #338 is slightly faster at 9.51 seconds vs. 9.57 (average over 5 runs).

Now we are well below litwr's 'pi-pc386.com' code size of 623 bytes, and faster than the theoretical 40MHz 386 at 10.4 seconds. Only Amiga makes it possible!

BTW I have changed my test setup slightly, so times will now be a bit quicker. I realized that the shell window can be made small and then enlarged after running to show all the text, and I changed the WorkBench screen to 4 colors because that is the Amiga's 'standard' resolution.
Thanks, for me without testing on real Amiga, i will say that 339 version must be fastest than 338. Perhaps it must be something related to caches or longword aligned code, but i dont know what.
BTW. How many max digits can be displayed by both version?

Last edited by Don_Adan; 25 June 2021 at 10:35. Reason: more info
Don_Adan is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
68020 Bit Field Instructions mcgeezer Coders. Asm / Hardware 9 27 October 2023 23:21
68060 64-bit integer math BSzili Coders. Asm / Hardware 7 25 January 2021 21:18
Discovery: Math Audio Snow request.Old Rare Games 30 20 August 2018 12:17
Math apps mtb support.Apps 1 08 September 2002 18:59

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 03:52.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 1.16010 seconds with 16 queries