MicroProgramming - Decrement jump not Zero - microprocessors

I'm trying to get my head around Micro Programming and OpCodes. I'm looking at DJNZ or Decrement Jump Not Zero. I've been trying to get this to work with no luck. My code with irrelevant parts removed is as follows.
044 alu:=ac If Z then goto 79
079 ac:=ac+(-1) read Goto 80
080 mar:=ac write Goto 0
My listing for OPCodes is this
DESP: sp:=sp-y
JNZE: if ac /= then pc:=x
So far I believe I have it to jump on not Zero to 79, then it might do a decrement and write back. I'm unsure.
I'm using this to test
begin: loco 8
loop1: jnze loop1
loop2: jump loop2
With this output
If someone can say if I'm on the correct lines and then help me implement the jump on NOT zero and give me a pointer on the correct way to decrement and write back it would be fantastic.
Unsure if this is the correct site, and I was unsure for the tags as well so if someone could fix or point me in correct direction would be great.

Related

Intepretation of output from register. AT90E32 + stm32

i have a problem with documentation, which i don't understand. Documentation is here:
Read sequence is on the page 31.
I want to read Phase C voltage RMS.
From this register i get in that order: 0011110010001111.
Value read should be 233.3V.
I am beginner and really don't know hot to interpret this. When i read first byte from right 11110001 that is 241. The next byte read from left is: 00111100 which is 60, but when i multiply this by 0.01V (in documentation is that 1LSB should be multiply'ed by 0.01 - what means 1LSB? ) i get 241,6 V. That is correct? Thanks for any help guys.

Set specific elements on a matrix to zero

I want to preserve some elements in a 36x18x12000 matrix and set everything else to zero. In particular, I'm interested in getting the values of a specific region in the 36x18 map through time. The code I'm trying to use for this is the following:
coflux_SAm(1:26,1:3,:)=0;coflux_SAm(35:36,11:18,:)=0
What I plan to do here is to keep the South American region (lon 27:34 ; lat 4:10 in the map) and delete the rest, basically. I'm getting pretty annoyed of finding that neither this line nor the loop:
for i=1:26
for j=1:3
coflux_SAm(i,j,:)=0;
end
end
for i=35:36
for j=11:18
coflux_SAm(i,j,:)=0;
end
end
are working. They seem to make random modifications in the matrix but I don't even find a pattern to it.
Sorry for the delay in putting the answer here, I just saw that I had to to close the thread. I copy and paste so it can be closed. Cheers
Ok, nevermind...I was obviously being silly and getting worried about the code and not the logic behind what I really wanted. I changed the code to: 'coflux_SAm(1:26,:,:)=0;coflux_SAm(35:36,:,:)=0; coflux_SAm(:,1:3,:)=0;coflux_SAm(:,11:18,:)=0;' and now it works. With the previous one I was deleting the intersection between longitude and latitude and not everything but what I needed...silly me. Thank you anyway if anyone bothered to have a look. Cheers!

Finding the first element less than a certain value in an unsorted vector (MATLAB)

Pretty simple, and I thought I knew what I was doing, but apparently not. Anyways.
I need to find the first element in a vector that is less than a specific value. Here is the code that I have been using:
t = 0:0.01:5;
u = ((2)*exp(-10.*t).*cos((4.*sqrt(6)).*t) + ((5)./sqrt(6)).*exp(-10.*t).*sin((4.*sqrt(6)).*t));
for a = 1:size(u)
if u(a) < (0.05)
disp(a)
break
end
end
The value that I'm trying to find is the first element less than 0.05, however, when I run my code, I don't get anything.
What could I be doing wrong?
Thanks!
#user2994291 has correctly pointed out where your loop based solution is going wrong (+1).
However I would also add that what you are trying to do can simply be accomplished by:
find(u < 0.05, 1, 'first')
Technically, the third input is not necessary - you could just use:
find(u < 0.05, 1)
However, I seem to recall reading at some point that find will work faster if you provide the third input.
The upper bound of your for loop is probably equal to 1.
In your case, u is a row vector (can't say 100% for sure in MATLAB as I only have access to GNU Octave right now), but calling size(u) will probably give back [1 501] as an answer. Your for-loop will select 1 as upper bound.
Try replacing size(u) with size(u,2) or, even better, with length(u). I get a = 24 as an answer.
Edit:
from your questions I assume you are a MATLAB beginner, therefore I strongly advise you to look into the built-in debugger (you can add breakpoints by clicking on the left vertical bar next to the desired line of code), this would have helped you identify the error with ease and will save you a lot of time in the future.

translating loop from Fortran to MATLAB

I'm currently translating code from Fortran to MATLAB manually, and I am unsure of how to translate part of it. (The entire code actually is a 2,000 line subroutine.) The code is below.
C Has series crossed neckline?
120 neckext=x(trough(peaknum-1))+
* dydx*real((t-trough(peaknum-1)))
if(x(t).lt.neckext) goto 130
C NO. Here if series has not crossed neckline, nor new trough found
C Check to see if new trough has been found.
t=t+1
if(t.ge.lastobs) goto 900
if(x(t).lt.min) then
min=x(t)
mindate=t
end if
troughid=min*(1.0+cutoff)
if(x(t).ge.troughid) goto 150
goto 120
C YES. Here if series crossed neckline before new trough found
130 dblcount=0
if(poscount.ge.1) then
DO 132 i=1,poscount
if((enterdt(i)-2.le.t).and.(t.le.enterdt(i)+2)) then
dblcount=dblcount+1
end if
132 continue
if(dblcount.ge.1) then
C write(30,2583) t,Cutnum
2583 format('DoubleCounting episode occurred at ',I5,
* ' with Cutoff = ',F3.1)
goto 150
end if
end if
My problem is with this part of the code:
if(x(t).ge.troughid) goto 150
goto 120
When I was translating this part in MATLAB, I was writing something like:
if x(t,:)>=troughid
t=marker;
minimum=x(t,:);
end
But I don't know what to do with the label 120. When I translate it, do I write that part again? Because from what I understand, when I go back to 120, the code will be running again. Thanks!
EDIT: As a response to Chris's question on what labels 150 and 900 do, I'll post them here.
150 t=marker
min=x(t)
And this is for the label 900.
C Last observation found. This iteration finished.
900 continue
As it should be clear by now, Matlab does not include any variant of a "goto" command. The core Matlab command set appear to be designed around the "structured programming" philosophy. (Which, if I remember my CS ancient history correctly, was the great debate prior to object oriented programming.) Wikipedia has a decent discussion of structured programming.
In the dark days before structured programming, people used to be very excited about flow charts, since that was one of the easiest ways to visualized and understand a piece of code using a lot of goto statements (now usually referred to as spaghetti code).
I suspect that you will need to flowchart the entire subroutine, and then decide which control flow constructs can best be used to recreate your code. If it is a relatively simple diagram, then you should be able to recreate the entire code with if statements or case statements, although a series of small helper functions may be more elegant. If it has a more complex structure, then it may take a little more creativity to translate.
You can wrap the first half of your code, until after the goto 120 in a while loop. You can then break out of this while loop when the condition if(x(t) .lt. neckext) is met. For example, the logic could look something like the following. Note that I have not tried to convert it all to MATLAB (that is your job!!) but hopefully it gets you started.
% Has series crossed neckline?
neckext = x(trough(peaknum-1)) + dydx*real((t-trough(peaknum-1)));
if (x(t) < neckext)
% Code below `goto 120` here...
else
while (x(t) >= neckext)
% Code above `goto 120` here...
end
end
% `goto 150` code here?
I'm not quite sure if the above is what you need, since without the full code I have no idea what goto 150 and goto 900 are supposed to do to the program flow (apart from making it hard to follow).
Almost all allowed goto's in Fortran can be translated into MATLAB by using while/break/continue constructs. I have written a (unreleased) program to automatically remove goto's from Fortran code, then I use my program, f2matlab, to translate the code to MATLAB/Octave.

Pi value estimation with series

Here's my problem:
Compute the value of π using the following series:
((π^2)-8)/16=[sum from 1 to pos. infinity] 1/(((2n−1)^2)*((2n+1)^2))
• Find the smallest number of terms required to obtain an absolute value of the error on π smaller than 10e−8.
Here's my code:
x=0;
for i=1:1000
x=x+(1/((((2*i)-1)^2)*(((2*i)+1)^2)));
z=sqrt((x*16)+8);
error=abs(z-pi);
if (error < 10e-8)
i
break
end
end
The answer that I get is 81 when the loop breaks, but it is not the right answer. I have been trying to figure out what is wrong with my code that it doesn't do what I need.
I've been staring at the code for quite a while and cant see where I made a mistake.
I found the problem. The error is supposed to be less than 10^-8 not 10e-8. Somehow the numbers got changed over when copying.