Is there a way to add code to an infinite z80 assembly loop? - calculator

A while ago, I asked what the fastest infinite loop was on a TI-84. One of the answers I got involved using an assembly infinite loop with this code:
AsmPrgm
18FE
However, this is a bit impractical, because it can only be exited with the reset button and doesnt run anything inside it.
Is there a way to put TI-Basic code inside of this loop and/or make it exit conditionally?
Here is the link to the original question and answer:
What is the fastest infinite loop in TI-84+ Basic?

$18FE is jr -2, which loops two bytes backwards, in on itself. You'll want the additional logic to come after the start of the loop to let you escape (i.e. checking for button presses), then just have it loop back to that label. To do that, you'd need to adjust the $FE value, as that's the distance to jump. It's a signed 8-bit value, so make sure you get all your conditional code in, then branch back depending on the number of bytes you've used.

Regarding your original (linked) question, jr $ is not the fastest loop possible on Z80, as the fastest one is jp $ (actually jp (hl)), where $ denotes the address of the current instruction.
The fastest exitable loop could be done in three ways, depending on what is your definition of 'loop' is and how the loop should be exited:
Use the interrupts to quit abovementioned loop: in this case, you should unwind stack in the interrupt (remove return address) and jump elsewhere.
Use the loop like this:
​
IN reg,(C)
JP cc,$-2
where IN reg,(C) command also sets S (sign), Z (zero) and P/V (parity) flags depending on the value read from port and JP cc uses one of those flags to continue the loop or leave it.
Use the HALT and exit it naturally with the interrupt.
It is known that Z80 executes HALT by continuously fetching the same byte following HALT instruction from the memory, then ignoring it and doing that until the interrupt is caught. This behaviour could be described as looping until the interrupt is caught. The root cause for such behaviour is that Z80 naturally does DRAM refresh every opcode fetch and this way the refresh is kept during HALT execution.

You can definitely make assembly programs exit conditionally. The command C9 is return, so if you have a program consisting of only AsmPrgmC9, running it as an assembly program will have it instantly finish (it will look the same as running a program with nothing in it). If you want to end the loop when some condition is met, then you'll need to start learning assembly as the answer will widely vary on what that condition is and what OS version/calculator you're using.

Related

Does adding breakpoint in a matlab m file make it run slower?

I have a matlab m file that basically has two sections
The first section contains a large loop that does operations on arrays of size 64, with the loop itself running about 2000 times
After this loop is finished, the second section contains code that isn't much computationally expensive
I need to invoke a breakpoint ( I do this by clicking on the left margin on the editor window) after the first section finishes, but whenever I set a breakpoint the first section of the program takes significantly longer to execute
I am not changing anything in the program itself. The breakpoint is never in the first section. The program runs really fast when there is no breakpoint (less than 10 seconds) as opposed to when I set a breakpoint after the first section (about 60 seconds)
Is this expected behaviour? Why is having a breakpoint causing the program to run slower? Is there a way to fix this?
MATLAB Version 7.9.0.529 (R2009b) 64 bit on Windows 10 64 bit Home edition
"Does adding breakpoint in a matlab m file make it run slower?": Yes.
In all languages*, debugging mode is slower because it requires extra power to be able to stop the code, and disables most of the optimization that the interpreter/compiler does.
Nothing really you can do against it (well, not debug, but that defeats the purpose hehe).
[*]: I know about

MIJ: execute imageJ (Fiji) macro until end in Matlab

I am using MIJ to execute an ImageJ macro within Matlab. The macro has to be executed multiple times in a "for" loop. The problem is that Matlab does not wait until the macro ends. Initially I solved the problem with a "while" loop, checking if the "Results" table generated from the macro was empty or not. However, it only solves the problem the first time, then from the second time the "Results" table is not empty anymore.
I also thought about generating a variable at the end of the macro and use it to check if the macro finished, but I don't know how to read it in Matlab.
Do you have any suggestion about how I can solve the problem?
Thanks a lot in advance,
Alessia
Here is an example of my code:
javaaddpath 'C:/Program Files/MATLAB/R2019a_x64/java/ij.jar'
javaaddpath 'C:/Program Files/MATLAB/R2019a_x64/java/mij.jar'
MIJ.start('C:/fiji-win64/Fiji.app/plugins');
IJ=ij.IJ();
macro_path=...
'C:/Macro_waterinoil.ijm';
for pos=1:16
im = mijread(strcat('E:/droplets.tif'));
figure(1)
imshow(im,[0 255])
IJ.runMacroFile(java.lang.String(macro_path));
res_Hough=0;
res_Hough=MIJ.getResultsTable();
while res_Hough==0;
res_Hough=MIJ.getResultsTable();
end
im_res=MIJ.getCurrentImage();
MIJ.run('Clear Results');
MIJ.run('Close All');
end
Edit: Ignore the below, I was on the right track but wasn’t paying as much attention as I should have been. I think this issue is the line right after you set res_Hough to 0 (i.e. res_Hough=MIJ.getResultsTable();). Try deleting it so that the next line is the while loop, then we can check the output and see if the below might also apply
If I am understanding correctly, you are using the while loop to continuously ping until the table is full, then store those values in res_Hough, right? I'm wondering if this is a limitation inherent to ImageJ/FIJI. The reason I think this might be the case is that a very simple explanation for your issue is that the table retains the previous values, and so will always be full after the first loop unless cleared manually somehow. Do you think that could be the case? Perhaps add a print statement after the while loop and see if it prints the same values for the duration of the for loop.
I suppose the next thing to do is for me to actually try to offer a solution regardless of the above. My idea is to try having the while loop check against the previous iteration's table values until they are different, then stash the updated values. Does that make sense? Something like:
while (res_Hough[i]==0) or (res_Hough[i-1]==MIJ.getResultsTable());
res_Hough[i]=MIJ.getResultsTable();
Where i is incremented by the for loop

Fortran and Eclipse: Displaying text in console

I'm having a small difficulty with Fortran 90 and Eclipse. I installed the "Photran" plugin to Eclipse, and have managed to compile everything perfect, and overall the program does what it has to do. The problem comes when displaying text in the Eclipse console. The code it self not that important, since it does what it has to do, but more the output generation.
The piece of the code I'm having trouble with is the following:
subroutine main_program
write(*,*) "Program begins!"
<Program that takes ~5mins to run>
write(*,*) "Program ends!"
end subroutine main_program
Specifically, the problem is that in the console, the first message should be shown immediately, "Program begins!", and after ~5 minutes it should show "Program ends!". It happens that both of these messages get displayed only after the program is done running, not while the programs is executing.
I have used:
subroutine main_program
print*, "Program begins!"
<Program that takes ~5mins to run>
print*, "Program ends!"
end subroutine main_program
but it keeps on doing the same thing. I saw a "similar" post earlier (can't find the link though, sorry about that) but it was not really what I was looking for.
OK, here's the answer. Insert the statement
flush 6
after the first write statement to have its output sent immediately to the console. Insert it anywhere else you wish once you understand what it is doing.
It is obvious (to me) from the situation OP describes that the output is being buffered, that is the program issues a write statement and passes the output off to the operating system which does as it damn well pleases -- here it waits until the program ends before writing anything to the console. I guess that its buffering capabilities have some limits and if the program exceeded them the o/s would empty its buffers prior to program end.
Fortran now (since 2003 I think) provides a standard way of telling the o/s to actually flush the buffer to the output device -- the flush statement. In its simplest form flush takes only one argument, the unit number of the output channel to be flushed. I guessed that OP had unit 6 connected to stdout (aka *), since this is a near-universal default configuration, though not one guaranteed by the Fortran language standard.
I don't think that flush * is correct.
If you have a pre-2003 compiler then (a) for Backus' sake update and (b) it is likely that it supports a non-standard way to flush buffers; if memory serves gfortran used to provide a subroutine which would be called something like call flush(6).
There are other ways, outside Fortran, to tell the o/s to write to disk (or console or what have you) immediately. Look at the documentation for your o/s if you are interested in them.

Set arbitrary breakpoint in debugger

I have been using the perl interactive debugger (basically perl -d script)
I have a script that has quite a lot of modules imported and I need to debug a problem.
What I do is start the debugger and go over lines, stepping into where necessary.
But this is tedious as I need to step into many lines of code and function calls.
Question: Let's say that after going over the lines of code I eventually step into function A::B::C::foo() of some module where is the problem I am debugging.
Is there a way to set a break point in that function in the beginning of the debugging session so that I jump there directly instead of going over the code line by line until I reach there?
I know that I can add a break point in the same file my debugger is currently but how can I add a breakpoint in a line that is outside of the debugger's scope at this point (to some arbitrary file/module that eventually the debugger would have reached)?
Note:
Just to clarify: It is not like A::B::C::foo() is in line X of the script. It is eventually called after going down the call chain of a lot other functions in many modules
You can set a breakpoint to a subroutine with the documented b sub syntax. In this case, just use
b A::B::C::foo
c
You may set a break point by defining file name and then line number
b YourModule.pm:line_number
where line number is inside the module function you want to break at.
You can even put a breakpoint on a sub that hasn't been loaded/defined yet using the postpone option:
b postpone Name::Of::Sub::Yet::To::Be::Created

How can I interrupt MATLAB when it gets really really busy?

I'm running a long simulation in MATLAB that I've realized I need to stop and rerun. However, MATLAB is really into this calculation, and it's stopped responding. How can I interrupt this run without killing MATLAB?
(I realize this is a problem with many Windows programs, but it's really acute with MATLAB.)
Go to the command window, and hit Ctrl-C a lot. From my experience, on a single-core machine you do not have a chance, unless you do lots of output. On a multi-core or multi-processor machine, you'll probably stop it eventually, but it takes time.
See also http://www.mathworks.com/support/solutions/en/data/1-188VX/index.html
Added: it is a good practice to (1) save a snapshot of your workspace before running anything really long and (2) within a very long calculation, write some of the variables to a file from time to time, so that you can resume the calculation if it was interrupted (by power failure, e.g.).
How well MATLAB responds to CTRL-C rather depends on what it's doing. If it's in the middle of a BLAS or LAPACK call for example, it will not respond until that call returns. If you're in a block of code where lots of lines of MATLAB are being executed, you can expect CTRL-C to be more responsive.
I have got a very simple trick to pause (or stop) a non-responsive execution.
If my simulation is running a long loop I always do the following:
for ii = 1:N
do_stuff();
clear empty_script;
empty_script;
end
And then create a file empty_script.m containing the following:
%keyboard
Whenever I want to pause execution I open an external text editor and uncomment the line saying keyboard in empty_script.m. That leaves me in debugging mode where I can watch variables, modify stuff or even stop the program.
Another strategy for dealing with this problem is to introduce a very short pause somewhere in the calculation (especially in a FOR or WHILE loop), as in:
for ii = 1:N
do_stuff();
pause(0.1);
end
This increases the chances that your maniacal Ctrl-C'ing will actually stop it.
you can find the MATLAB process in the windows task manager and set the priority as high or low and let other program to have lower or higher priority. In my experience, it is an efficient way.
if you wont to stop and rerun then killing is not bad choise
Go to windows task manager-> Processes then fined MATLAB.exe and push the End Process button