It is currently Tue Oct 22, 2019 4:51 am

 All times are UTC

 Page 1 of 1 [ 2 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: hex to number in any base...Posted: Sat Nov 17, 2018 9:33 am

Joined: Sat May 20, 2017 3:07 pm
Posts: 6
Hi all,

I am slowly implementing the easy68k traps in my bios rom mostly as a learning aid.
I have just done the trap print a hex number in any base using the divide and conquer method
To test it i call it 4 times and ask it to display the number 0x1234 1st as decimal then octal then hex and finally binary
( tests chosen as there the bases supported by my on screen calculator )
i get the correct result for decimal/octal and binary but the wrong result for hex!
So the question is have i mucked it up or is this method not able to display the result in the same base as the source number ?

Posted the code below , Without doubt there will be possible improvments that could be made
but i am pleased that it seems to be okay for any base but hex which has me baffled.
below the code i have cut and pasted the result after calling in assorted bases.

Code:
;---------------------------------------
; 15   ; Display the unsigned number in D1 converted to number base (2 through 36) contained in D2
;   For example, to display D1 in base16 put 16 in D2.B
;    Values of D2 outside the range 2 to 36 inclusive are ignored.
;   Note only good for values up to FFFF ( word size )
;---------------------------------------
_trap15_F:
even            ; Ensure compiler places entry point word alignment
; D2 = divisor ( number base )
; D1 = number to convert.
cmp   #\$0,D1         ; compare target with zero
beq   NumbIsZero      ; Bail out.
;----
cmp   #\$2,D2         ; Compare D2 ( divisor ) with 2
blo   InvalidDiv      ; if divisor is less than 2 it's stupid ( 2 for basic binary )

; if we get here we have at least somethiong to do
; Start by clearing the buffer space.
jsr   ClearWorkBuff      ; clears 1024 bytes
lea   WorkBuff,A1      ; Move pointer back to start of now cleared and nulled buffer buffer.
; Okay cleared a buffer, Sanity checked inputs D2 = divisor, D1 = number to convert.
; Now convert hex number to

ConvLoop:
even
move.l   #\$0,D0         ; Clear D0
move.l   #\$0,D3         ; Clear D3
move.l   #\$0,D4         ; Clear D4

divu.w   D2,D1         ; Divide D1 by the divisor(D2)--> D1 now contains lowword=quotent, highword remainder
move.w   D1,D4         ; D3 now holds the Quotent
swap   D1         ; Swap remainder into low word
move.w   D1,D3         ; D4 now holds the remainder.
move.l   #\$0,D1         ; D1 = empty, D4 = remainder, D3 = quotent, D2 divisor
move.l   D3, D0         ; copy D3 to D0

lea   msgTable,A2
move.b   (A2),D0         ;
move.b   D0,(A1)+      ; save to buffer.

move.w   D4,D1         ;
cmp.w   #\$0,D1         ; is remainder is 0 then were done.
beq   JobDone         ; bail out were all done.
bra   ConvLoop      ; else go round again

JobDone:
even
lea   WorkBuff,A1
; We should now have the result in buffer BUT
; The string is reversed in the buffer.
bra   ReverseString      ; This actually prints the string to screen in reverse.

MOVEM.L (A7)+,D0-D7/A0-A6    ; POP ALL REGISTERS ( saved in base trap ) ( 14 )
RTE            ; Return from exception
;----

NumbIsZero:
move.b   #'0',(A1)+
move.b   #\$0,(A1)
MOVEM.L (A7)+,D0-D7/A0-A6    ; POP ALL REGISTERS ( saved in base trap ) ( 14 )
RTE            ; Return from exception
;----
InvalidDiv:
lea   msgDivError,A0      ; CR,LF,'Invalid Divisor must be in the range 2 - 36',CR,LF,0
jsr   PrintString      ; Print error message and return.
MOVEM.L (A7)+,D0-D7/A0-A6    ; POP ALL REGISTERS ( saved in base trap ) ( 15 )
RTE
;----

ReverseString:            ; Assumes the string is at WorkBuff and is
lea   WorkBuff,A1      ; in reverse order
move.l   A1,A2         ; make a copy
jsr   GetStrLength      ; Checks length of string pointed to by A1 len is returned in D2 includes null
sub.b   #\$1,D2         ; Ignore the null byte
add.l   D2,A1         ; make A1 point at end of string.
Again:
move.b   (A1),D0         ; get char
jsr   OutChar         ; print it
sub.l   #\$1,A1         ; move pointer back 1 char
cmp.l   A1,A2         ; check if we have reached the start
beq   done         ; do the end routine
bra   Again         ; else do another char
done:
move.b   (A1),D0         ; get char
jsr   OutChar         ; print it
MOVEM.L (A7)+,D0-D7/A0-A6    ; POP ALL REGISTERS ( saved in base trap ) ( 14 )
RTE            ; Return from exception
;----

;---------------------------------------
; Returns the length of an ascii string.
; On entry A1 points at start of string.
; On exit D2 holds the length of the -
; string including the terminating null.
; On exit only D2 is changed...
;---------------------------------------
GetStrLength:            ;
move.l   D0,-(A7)      ; Save D0
move.l   A1,-(A7)      ; Save A1
move.l   #\$0,D2         ; Zero D2
Back:               ;
move.b   (A1)+,D0      ; Get char from buffer.
cmp.b   #\$0,D0         ; Is it a NULL.
beq   DoneIt         ; yes so return.
bra   Back         ; No so return and do it again.
DoneIt:               ; Bail out routine.
move.l   (A7)+,A1      ; Restore A1
move.l   (A7)+,D0      ; Restore D0
rts            ;
;---------------------------------------

;---------------------------------------
; Clear the supervisors temp work buffer.
; 1024 bytes ( 0x400 ) cleared to null bytes.
; No registers changed.
;---------------------------------------
ClearWorkBuff:            ;
move.l   A0,-(A7)      ; save A0
move.l   A1,-(A7)      ; save A1
lea   WorkBuff,A0      ; Get address of work buffer.
move.l   A0,A1         ; Copy start address to A1.
ClearMore:
move.b   #\$0,(A0)+      ; Save a null byte and bump ptr.
beq   BuffDone      ; All done.
bra   ClearMore      ; Do some more.
BuffDone:            ;
move.l   (A7)+,A1      ; Restore A1
move.l   (A7)+,A0      ; Restore A0
rts            ; return whence we came.
;---------------------------------------
-----------------------------------------------------------------------
test results
-----------------------------------------------------------------------
About to ask for the number \$1234 via trap 15 F thrice!
Once as a decimal number and once as an octal number and finaly a hex number
The result should be 4660, 11064, 1234, 1001000110100
Calling for decimal 1st and the result is >4660
Calling for octal 2nd and the result is >11064
Calling for hex last and the result is >15AA
Calling for hex last and the result is >1001000110100

Top

 Post subject: Re: hex to number in any base...Posted: Sun Nov 18, 2018 1:14 pm

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1102
A quick test reveals many assembly errors in the code.

_________________
Prof. Kelly

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 2 posts ]

 All times are UTC

#### Who is online

Users browsing this forum: No registered users and 1 guest

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ EASy68K Forum    FAQ    Latest Features    EASy68K Questions    68000 Programming Questions    Wish List    Wishes Granted    Undocumented Features    Documented Features    General Discussion    EASy68K Projects