EASy68K  
It is currently Fri Dec 13, 2019 5:02 pm

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
PostPosted: Sat Nov 17, 2018 9:33 am 
Offline

Joined: Sat May 20, 2017 3:07 pm
Posts: 6
Hi all,
I am a tad confused,

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
   add.l   D0, A2         ; add the offset
   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.
   add   #$1,D2         ; add 1 to length.
   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.
   add.l   #$400,A1      ; Add 400h or 1024 decimal.
ClearMore:
   move.b   #$0,(A0)+      ; Save a null byte and bump ptr.
   cmpa.l   A0,A1         ; compare address start with end.
   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.
;---------------------------------------
(Admin: Added code tags.)
-----------------------------------------------------------------------
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
 Profile  
 
PostPosted: Sun Nov 18, 2018 1:14 pm 
Offline
User avatar

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

_________________
Prof. Kelly


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 5 guests


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

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group