English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 22 June 2021, 00:28   #321
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
Quote:
Originally Posted by a/b View Post
-2 bytes due to alignment (extra zero at the end is never used):
Code:
;         moveq #msg2-msg3+1,d3
         moveq #msg2-msg3,d3
...
;msg3 dc.b ' digits will be printed'
;msg2 dc.b 10,0
msg3 dc.b ' digits will be printed',10
msg2
	even
Since there's some code in between that could be activated (dma on/off)... I'm not familiar with vasm syntax, in asm-one I'd do (and yes, you can do AO there and it will auto-correct it):
Code:
	IFGT	.write-*-128
	bsr.w	.write
	ELSE
	bsr.b	.write
	ENDC	; IFGT
Ok, changed. Most assemblers auto reasembled bsr.b to bsr.w. I prefer easy code and dont like auto optimisations.
Don_Adan is offline  
Old 22 June 2021, 00:33   #322
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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   #323
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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   #324
a/b
Registered User

 
Join Date: Jun 2016
Location: europe
Posts: 393
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   #325
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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   #326
a/b
Registered User

 
Join Date: Jun 2016
Location: europe
Posts: 393
Yup, that would work. -2*2 bytes.
a/b is offline  
Old Yesterday, 00:45   #327
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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; Yesterday at 00:56.
Don_Adan is offline  
Old Yesterday, 02:08   #328
Bruce Abbott
Registered User

Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 678
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 Yesterday, 02:10   #329
a/b
Registered User

 
Join Date: Jun 2016
Location: europe
Posts: 393
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 Yesterday, 02:40   #330
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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 Yesterday, 02:55   #331
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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; Yesterday at 04:59.
Don_Adan is offline  
Old Yesterday, 04:18   #332
a/b
Registered User

 
Join Date: Jun 2016
Location: europe
Posts: 393
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 Yesterday, 05:00   #333
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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 Yesterday, 23:43   #334
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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 Today, 00:33   #335
a/b
Registered User

 
Join Date: Jun 2016
Location: europe
Posts: 393
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 Today, 01:39   #336
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 53
Posts: 1,344
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  
 


Currently Active Users Viewing This Thread: 3 (1 members and 2 guests)
Mixel
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
68060 64-bit integer math BSzili Coders. Asm / Hardware 7 25 January 2021 21:18
68020 Bit Field Instructions mcgeezer Coders. Asm / Hardware 7 07 February 2019 14:59
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:13.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.
Page generated in 0.19951 seconds with 14 queries