EASy68K  
It is currently Tue Apr 07, 2020 11:22 am

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Thu Mar 04, 2010 12:35 am 
Offline

Joined: Thu Mar 04, 2010 12:16 am
Posts: 6
Hello everyone! can you help me fix this code. im trying to convert assumed hex input character to decimal so that i can do the desired operation. attached herewith is the copy of my code. hope you can help me with this. also this keeps running infinte. :( also, i would also tell if the single precision format is infinite or not a number.

example: 1234(hex)+5678(hex)=68AC(hex)


Code:
   ORG $1000   
      
*MAIN FUNCTION   

*Displays the title of the program and prompt for count of input numbers.    
START   MOVE #13,D0   
   LEA INTROMSG,A1   
   TRAP #15   
      
INPUT   MOVE #14,D0   
   LEA OPAMSG,A1   
   TRAP #15   
   
   MOVE #2,D0   
   TRAP #15

   BSR STR1CONT
      
   MOVE D1,D4
   
   MOVE #14,D0   
   LEA OPBMSG,A1   
   TRAP #15   
      
   MOVE #2,D0   
   TRAP #15
   
   BSR STR2CONT
   
   MOVE D1,D5

   MOVE #14,D0   
   LEA OPERATIONMSG,A1   
   TRAP #15   
      
   MOVE #4,D0   
   TRAP #15

   CMP #1,D1
   BSR ADD
   
   CMP #2,D1
   BRA ABSUB
   
   CMP #3,D1
   BRA BASUB
   
   CMP #4,D1
   BRA MUL
   
   CMP #5,D1
   BRA ABDIV
   
   CMP #6,D1
   BRA BADIV
      
STR1CONT MOVE.B   (A1)+,D1

   BSR   END1
   
   BSR   CONVERT1
   
   RTS
   
END1   CMP.B   #0,D1
   BNE   COUNT1   
   
COUNT1   ADD.B   #1,D2
   
   CMP.B   #0,D1
   BNE   STR1CONT
   
   RTS
   
STR2CONT MOVE.B   (A1)+,D1

   BSR   END2
   
   BSR   CONVERT2
   
   RTS
   
END2   CMP.B   #0,D1
   BNE   COUNT2   
   
COUNT2   ADD.B   #1,D3
   
   CMP.B   #0,D1
   BNE   STR2CONT
   
   RTS

CONVERT1 MOVE   -(A1),D1
   MULU   #16,D1
      
   CMP   #0,D2
   BSR   HEX_DEC
   
HEX_DEC   MULU   #10,D1
   ADD   D1,D6   
   
   DBRA   D2,CONVERT1
   RTS
   
CONVERT2 MOVE   -(A1),D1
   MULU   #16,D1
      
   CMP   #0,D3
   BSR   HEX_DEC
   
   DBRA   D3,CONVERT2
   RTS
   
ADD   ADD.L   D4,D5
   MOVE   D4,D1
   
   MOVE   #15,D0
   MOVE   #16,D2
   TRAP   #15
   
   RTS
   
ABSUB
BASUB
MUL
ABDIV
BADIV   
   

DISPLAY MOVE    #14,D0   
   LEA    DISPMSG,A1   
   TRAP    #15   
      
   MOVE    #4,D0   
   TRAP    #15
   
   MOVE   #15,D0
   MOVE   #16,D2
   TRAP   #15

INVALID   MOVE #14,D0   
   LEA NANMSG,A1   
   TRAP #15
   
   
   MOVE.B   #9,D0
   TRAP   #15   
   
*VARIABLES AND STRINGS

*Variables   
OPA   DC.L   0
OPB   DC.L   0
CNT1   DC.W   0
CNT2   DC.W   0
ANSWER   DC.L   0
CHOICE   DC.W   0
CR   EQU   $0D      Control characters not predefined by Easy68k
LF   EQU   $0A

*Strings for message prompt and display      
INTROMSG   DC.B 'SINGLE PRECISION FLOATING POINT CALCULATOR',CR,LF,0   
OPAMSG      DC.B 'Enter Operand A (in hex):  ',0
OPBMSG      DC.B 'Enter Operand B (in hex):  ',0      
OPERATIONMSG   DC.B  'Choose the corresponding number for the desired operation.',CR,LF
      DC.B '[1] A+B [2] A–B [3] A*B',CR,LF,0
DISPMSG      DC.B CR,LF,0,'The result of the operation is: ',0
TRUNCMSG   DC.B 'Number truncated. ',CR,LF,0   
NANMSG      DC.B 'Input is Not A Number. ',CR,LF,0
INFMSG      DC.B 'Input is Infinity. ',CR,LF,0

      
   END   START
[/quote]

Be waiting for your help, prof kelly. thanks. :lol: :lol:


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2010 1:36 pm 
Offline

Joined: Thu Mar 04, 2010 1:09 pm
Posts: 4
Heya!

I recently discovered this website by mistake and I've never used this simulator, so my knowledge of the simulator specific features won't be very good. But I do have some experience programming real 68000 computers.

So, I thought I'd try to help.

Code:
INPUT   MOVE #14,D0   
   LEA OPAMSG,A1   
   TRAP #15   
   
   MOVE #2,D0   
   TRAP #15


As I understand it, the first TRAP will print the message pointed to by A1, which is fine.

But the 2nd TRAP reads a string from the keyboard and stores it in the memory location pointed to by A1, which you haven't changed from the previous TRAP.

In other words, you'll store your inputted string over the top of your message. And if the inputted string is long enough, it will also overwrite other messages.

So that's one potential problem. But can be ignored for now as long as you keep your inputted strings small.

Anyway, I follow your programme a little more and come upon this

Code:
STR1CONT MOVE.B   (A1)+,D1

   BSR   END1
   
   BSR   CONVERT1
   
   RTS
   
END1   CMP.B   #0,D1
   BNE   COUNT1   
   
COUNT1   ADD.B   #1,D2
   
   CMP.B   #0,D1
   BNE   STR1CONT
   
   RTS


If you look at the first BNE instruction, it's "Branch on Not Equal". So if D1 isn't #0, it will branch to COUNT1

But!!!

COUNT1 is the very next instruction. So even if the branch isn't taken, it'll end up there anyway. So basically it makes your BNE instruction pointless.

If the processor DOESN'T branch, then the processor will simply execute the next instruction after the BNE. But if it DOES branch, it'll still end up at the next instruction.

Also in STR1CONT, you're using BSR END1( Branch to SubRoutine ), but you have a BNE back to STR1CONT from END1.

I'm not quite sure what you're trying to achieve with these subroutines, but you're running the risk of messing up your stackpointer, by using more BSRs than RTSs

After that point, I completely lose track of what you're aiming at. Sorry.

So, I hope these points have helped. Like I said, I'm familiar with the 68000, but not with this simulator. So I may have made some mistakes in understanding what's going on. If so, then I apologise.

You might want to wait for a better reply, from someone with more experience.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2010 12:24 am 
Offline

Joined: Thu Mar 04, 2010 12:16 am
Posts: 6
Thank you very much for your reply. I'm now trying to revise all of what i've done. :D The really problem for me is how to convert the string into hex. btw, will this way of input be the same even if it is specified that we'll be using single precision format or will it matter only on the operations? thanks. i'll try to post soon my latest copy. Cheers! :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2010 9:59 am 
Offline

Joined: Thu Mar 04, 2010 1:09 pm
Posts: 4
assembly wrote:
Thank you very much for your reply. I'm now trying to revise all of what i've done. :D The really problem for me is how to convert the string into hex. btw, will this way of input be the same even if it is specified that we'll be using single precision format or will it matter only on the operations? thanks. i'll try to post soon my latest copy. Cheers! :)


I'm not quite sure what you mean by "will this way of input be the same even if it is specified that we'll be using single precision format or will it matter only on the operations?"

Just remember, when you input a string, it is a string of ASCII characters that get stored to memory. If you use instruction number 2 in TRAP #15, and enter the string '123abc' which is a hexadecimal number, in memory you will have 49,50,51,97,98,99,0, which represents '123abc' in ASCII.
To convert to digits you can use, you can subtract 48 ( ASCII character zero 0 ) from a digit, and that will give you the correct answer if the digit was from zero to nine.

For the example I gave above "49,50,51,97,98,99", subtracting 48 from each digit gives "1,2,3,49,50,51" which is correct for the first three digits, but not for the last three.

To convert lower case ASCII letters a-f to numbers, you'll have to subtract a different number. For lower case, you'd subtract the ASCII code for 'a' and then add 10. In other words, subtract 87

For the example above, "97,98,99", become "10,11,12", which is the correct number for hexadecimal a,b and c digits. Also, upper case letters have a different ASCII code too, so you'll also have to take that into account.

Basically, just be aware that you'll have to treat ASCII characters 0 to 9 differently from letters a to b. But you may have known all this already. Sorry if I've been telling you things you already knew =X

Ignore everything from here onwards if you want. It's a bit technical, and might just confuse things and you don't really need to know it.

I notice you use the MULU instruction in the programme you posted. Which is fine. But there's a few limits with this command.

The first being, it will only multiply 16 bit numbers together, and give a 32 bit answer. You can't multiply 32 bit numbers together with it in the 68000 processor, because a 32 bit number multiplied by a 32 bit number could give a 64 bit answer, which wouldn't fit in the 68000s 32 bit registers.

The second problem with MULU is less important for an emulated 68000. But that problem is the MULU command is SLOOOW. On the real 68000, it takes something like 40-50 machine cycles to achieve a result, which is forever in assembly programming.

But, there's a cheat you can use to multiply faster, and using 32 bit numbers if you want. You use the command "LSL". Logically Shift Left. What this does, is shift all the bits to the left by a specified amount. For example

Code:
MOVE.B #%00010110,d0
LSL.B #1,d0


Command 1 puts the binary number %00010110 in the D0 register
Command 2 then shifts the bits left by the specified 1 place
So after than comand D0 contains %00101100

"Okay, so what?" you may be thinking. But we've just multiplied that number by 2

Don't believe me? Look. ( I'm assuming you know how to convert binary to decimal )

%00010110 = 22
%00101100 = 44

All without a mulu in sight. So how about we shift it again?

%01011000 = 88

and again?

%10110000 = 176. Which is double 88

Well, if you multiply something by 2 twice, that's the same as multiplying by 4. And if you multiply something by 2 three times, that's the same as multiplying by 8. And if you multiply something by 2 FOUR times, that's the same as multiplying by 16

So, if you shift all the bits in a number left by four places, you'll have multiplied it by 16.

So LSL.W #4,d0 gives the same result as MULU #16,d0

But LSL isn't limited to Word and Byte sizes. You can LSL.L #4,d0, which will multiply a 28 bit number by 16. With the left most bits falling off into nothing.

For example. %00001001101010010111000000010111 = 162099223 = $09A97017
Shifted 4 bits. %10011010100101110000000101110000 = 2593587568 = $9A970170

Which is correct, and something you couldn't do with just a single MULU command.

Anyway, if you didn't follow that last part, then nevermind. You can stick with MULU if you're happy using 16 bit numbers ( $0000 to $FFFF )

It's just a useful trick.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2010 12:55 pm 
Offline

Joined: Thu Mar 04, 2010 12:16 am
Posts: 6
wow! pretty good reply, sir/madam. :D be implementing it in my code.

what i mean by the "way of input" is: will there something be unusual to happen if it is specified that it should be a single precision format or is it just normal way of inputting the number 123.232 and 231.783?

hope i made it clear. :) thank you. try to post my working code soon. :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2010 2:08 pm 
Offline

Joined: Thu Mar 04, 2010 1:09 pm
Posts: 4
If you're asking about floating point mathematics, then I'm sorry to say I've very little experience with it.

The 68000 has no built in ability to work with floating point numbers. If you want to use single precision 32bit floating-point mathematics, you'll have to write your own routines, or get some from somewhere. It's just not something I've ever really tried to do.

The 68040 was the first 68k processor to have built in ability to work with floating point maths, and I never owned one.

Sorry


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 06, 2010 2:35 am 
Offline

Joined: Thu Mar 04, 2010 12:16 am
Posts: 6
Hello! got a lot of insights from you but i'm still finding trouble in converting the string but the operations are now working.

i'm posting my work here. the problem here is that it only operates when only one hex number is inputted. i'm trying to traverse the string and get each part of the string's place value but it seems the loop becomes infinite. once I already got the decimal value of the string, i think i can manage it already. can you help me fix this one? :D

also, is there any shorter way where in i would compare only the string variables with 0-9,a-f,A-F not one by one? :D

Code:
   ORG $1000   
      
*MAIN FUNCTION   

*Displays the title of the program and prompt for count of input numbers.    
START   MOVE #13,D0   
   LEA INTROMSG,A1   
   TRAP #15   
      
INPUT   MOVE #14,D0   
   LEA OPAMSG,A1   
   TRAP #15   
   
   MOVE #2,D0   
   TRAP #15

   BSR STRCOUNT
   MOVE D2,D1
   
   MOVE #3,D0
   TRAP #15
   
   MOVE D1,D4
   
   MOVE #14,D0   
   LEA OPBMSG,A1   
   TRAP #15   
      
   MOVE #2,D0   
   TRAP #15
   
   MOVE #0,D2
   MOVE #0,D3

   BSR STRCOUNT
   MOVE D2,D1
   
   MOVE #3,D0
   TRAP #15
   
   MOVE D1,D5

   MOVE #14,D0   
   LEA OPERATIONMSG,A1   
   TRAP #15   
      
   MOVE #4,D0   
   TRAP #15

   CMP #1,D1
   BEQ ADD
   
   CMP #2,D1
   BEQ ABSUB
   
   CMP #3,D1
   BEQ MUL
   
   CMP #4,D1
   BEQ ABDIV
   

ADD   ADD   D4,D5
   MOVE   D5,D1

   BRA DISPLAY

ABSUB   SUB   D5,D4
   MOVE   D4,D1
   
   BRA DISPLAY

MUL   MULU   D4,D5
   MOVE   D5,D1
   
   BRA DISPLAY
ABDIV   DIVU   D5,D4
   MOVE   D4,D1
   
   BRA DISPLAY

DISPLAY MOVE    #14,D0   
   LEA    DISPMSG,A1   
   TRAP    #15
   
   MOVE   #15,D0
   MOVE   #16,D2
   TRAP   #15

   MOVE #9,D0
   TRAP #15
   
*Variable, Subroutines

STRCOUNT MOVE.B   (A1)+,D1

   CMP #'0',D1
   BEQ NUMB   
   CMP #'1',D1
   BEQ NUMB   
   CMP #'2',D1
   BEQ NUMB   
   CMP #'3',D1
   BEQ NUMB
   CMP #'4',D1
   BEQ NUMB
   CMP #'5',D1
   BEQ NUMB   
   CMP #'6',D1
   BEQ NUMB
   CMP #'7',D1
   BEQ NUMB
   CMP #'8',D1
   BEQ NUMB
   CMP #'9',D1
   BEQ NUMB
   CMP #'A',D1
   BEQ CHARU   
   CMP #'B',D1
   BEQ CHARU   
   CMP #'C',D1
   BEQ CHARU   
   CMP #'D',D1
   BEQ CHARU
   CMP #'E',D1
   BEQ CHARU
   CMP #'F',D1
   BEQ CHARU   
   CMP #'a',D1
   BEQ CHARL
   CMP #'b',D1
   BEQ CHARL
   CMP #'c',D1
   BEQ CHARL
   CMP #'d',D1
   BEQ CHARL
   CMP #'e',D1
   BEQ CHARL
   CMP #'f',D1
   BEQ CHARL

   CMP #0,D1
   BEQ MOVE
   
   CMP.B #0,D1
   BNE STRCOUNT
   
   RTS
   
COUNT   CMP #0,D1
   BEQ MOVE
   
   CMP #0,D1
   BNE STRCOUNT

NUMB   CMP #0,D1
   BEQ MOVE
   
   SUB #48,D1
   MOVE D1,D2
      
   CMP #0,D1
   BNE STRCOUNT      

CHARU   CMP #0,D1
   BEQ MOVE
   
   SUB #55,D1
   MOVE D1,D2

   CMP #0,D1
   BNE STRCOUNT      

CHARL   CMP #0,D1
   BEQ MOVE
   
   SUB #87,D1
   MOVE D1,D2

   CMP #0,D1
   BNE STRCOUNT
   
POWER   SUB #1,D3

   CMP #0,D3
   BEQ ONE
   
EXPO   MULU #10,D1
   DBRA D3,EXPO
   
   RTS
   
ONE   MOVE #1,D1
   RTS
   
MOVE   RTS


INVALIDIN
   MOVE #14,D0   
   LEA INVINMSG,A1   
   TRAP #15
   
   
   
*VARIABLES AND STRINGS

*Variables   
OPA   DC.L   0
OPB   DC.L   0
CNT1   DC.W   0
CNT2   DC.W   0
ANSWER   DC.L   0
CHOICE   DC.W   0
CR   EQU   $0D      Control characters not predefined by Easy68k
LF   EQU   $0A

*Strings for message prompt and display      
INTROMSG   DC.B 'FLOATING POINT CALCULATOR',CR,LF,0   
OPAMSG      DC.B 'Enter Operand A (in hex):  ',0
OPBMSG      DC.B 'Enter Operand B (in hex):  ',0      
OPERATIONMSG   DC.B  'Choose the corresponding number for the desired operation.',CR,LF
      DC.B '[1] A+B [2] A minus B',CR,LF
      DC.B '[3] A*B [4] A/B',CR,LF,0
DISPMSG      DC.B 'Result: ',0
TRUNCMSG   DC.B 'Number truncated. ',CR,LF,0   
INVINMSG   DC.B 'Invalid input. Only 0-9,A-F are valid. ',CR,LF,0
NANMSG      DC.B 'Input is Not A Number. ',CR,LF,0
INFMSG      DC.B 'Input is Infinity. ',CR,LF,0

      
   END   START

Thanks. This will be a lot of help! :D


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 07, 2010 10:07 am 
Offline

Joined: Thu Mar 04, 2010 1:09 pm
Posts: 4
Quote:
also, is there any shorter way where in i would compare only the string variables with 0-9,a-f,A-F not one by one?


I'm not sure how much I should tell you, or let you figure out on your own. I wrote a routine that would convert ASCII 0-9 and A-F into a number. But I thought you might prefer to figure it out your self. So I won't post it unless you ask. But here's a few hints you might find useful

BRA = BRAnch. This branch will always be taken
BLO = Branch Lower. This branch will be taken if the comparison is lower
BLS = Branch Lower Same. This branch will be taken if the comparison is lower or equal
BEQ = Branch EQual. This branch will be taken if the comparison is equal.
BNE = Branch Not Equal. The branch will be taken if the comparison is not equal
BHS = Branch Higher Same. This branch will be taken if the comparison is Higher or Equal
BHI = Branch Higher. This branch will be taken if the comparison is Higher

BLO, BLS, BHS and BHI all work on UNSIGNED numbers. There are a different bunch for signed numbers, but this is already getting a bit long, so I'll skip it for now.


BLO
Code:
             CMP.B          #36,d1     ; Compare d1 to #36
             BLO            Branch     ; Branch if d1 is lower than #36
             ???                       ; This line will be reached if the branch ISN'T taken, because d1 isn't lower than 36. In other words, we'll get here id d1 is 36-255 ( 255 cause we're using CMP.B with B meaning Byte. And bytes hold a number from 0 to 255 )

Branch:       XXX           Blah       ; Here will be Branched to if d1 is 0-35



BLS
Code:
             CMP.B          #36,d1     ; Compare d1 to #36
             BLS            Branch     ; Branch if d1 is lower than or same as #36
             ???                       ; This line will be reached if the branch ISN'T taken, because d1 isn't lower than or equal to 36. In other words, we'll get here id d1 is 37-255 ( 255 cause we're using CMP.B with B meaning Byte. And bytes hold a number from 0 to 255 )

Branch:       XXX           Blah       ; Here will be Branched to if d1 is 0-36



BHS
Code:
             CMP.B          #36,d1     ; Compare d1 to #36
             BHS            Branch     ; Branch if d1 is higher than or same as #36
             ???                       ; This line will be reached if the branch ISN'T taken, because d1 isn't higher than or same as 36. In other words, we'll get here id d1 is 0-35

Branch:       XXX           Blah       ; Here will be Branched to if d1 is 36-255. 255 cause we used CMP.B.


You can probably see where this is going with BHI, so no need for me to tell you.

Anyway, you might not think that has helped very much, but here's something you might try

Code:
CMP #'0',d1          ; Compare d1 with ASCII '0' zero
BLO NotADigit        ; Branch if character is below ASCII '0', and so can't be a hex digit

CMP #'9',d1          ; To get here, d1 has to be above or equal to ASCII '0'
BLS ZeroToNine       ; Branch if character is below or equal to ASCII '9'

CMP #'a',d1
BLS OverNineBelowA   ; Branch is character is below ASCII 'a'

CMP #'f',d1
BHI TooHigh          ; Branch if ascii character is over 'f' so can't be a hexadecimal ASCII digit


After that, you'll either have branched to NotADigit, if the character is below ASCII '0'.
ZeroToNine, if the character is from '0' to '9'.
OverNineBlowA, if the character is over '9' but below 'a'
TooHigh, if the character is over 'f'
And we won't have branched at all if the character is from 'a' to 'f'

There are plenty of ASCII tables you can look at on the internet, just by searching for "ASCII"


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 07, 2010 1:07 pm 
Offline
User avatar

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1118
There is also an ASCII table in the EASy68K help.

_________________
Prof. Kelly


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 8 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