HP Forums
newRPL - build 1255 released! [updated to 1299] - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: Not HP Calculators (/forum-7.html)
+--- Forum: Not quite HP Calculators - but related (/forum-8.html)
+--- Thread: newRPL - build 1255 released! [updated to 1299] (/thread-9700.html)

Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33


RE: newRPL - build 1255 released! [official and unofficial] - rprosperi - 06-05-2019 01:04 PM

(06-05-2019 06:51 AM)Martin Hepperle Wrote:  Out of curiosity I bought a Hp 39gs and flashed newRPL into the device (I did not want to destroy my HP 50g).

Another idea is to get a 49g+ for your host platform. They are MUCH cheaper than 50g's but have the correct keyboard, and much more memory. The 39gs has a smaller ROM capacity than the 49g+/50g, and Claudio has warned that the 39gs ROM capacity is nearly full now and soon will no longer be able to load the newRPL image.


RE: newRPL - build 1255 released! [official and unofficial] - bzoom - 06-05-2019 03:42 PM

(06-02-2019 06:01 PM)Claudio L. Wrote:  If/when you fix it, please let me know which debugger/dongle you used so I can get it and do the same on my 50g. I bought a Flashcat that supposedly supported this flash chip, but doesn't through the old JTAG from the ARM9 cores so I wasted my money. I want to find something that's proven to work before I spend any more money on it.

Not there yet but some progress with openocd + raspberry pi.
https://iosoft.blog/2019/01/28/raspberry-pi-openocd/

flash bank configuration needs still some tuning, i/o not working atm

[attachment=7357]


RE: newRPL - build 1255 released! [official and unofficial] - Claudio L. - 06-06-2019 01:54 AM

(06-03-2019 05:26 PM)3298 Wrote:  I have a theory regarding the recent flashing failures on the 39gs ... if:
- the firmware image is longer than the flash space (1MiB) minus the length of the bootloader (probably 16KiB, because that's the length on 49g+ and 50g),
- the firmware update code doesn't check if the firmware fits into 1MiB (either because it doesn't check at all, or because Kinpo goofed and left it at the 2MiB appropriate for 49g+ and 50g), and
- the flash memory repeats in the adress space, e.g. by leaving the extra address pin unconnected,
then a catastrophic buffer overflow happens during the update process. The write process would fill the flash, then wrap around and overwrite the bootloader by writing into the start of the mirror image. That would not only crash as the update code deletes itself during the sector clear part of the write operation, but also brick the machine preventing any further use as the rest of the bootcode goes poof along with the updater. The firmware was displayed to me as 1020 KiB long, so the first condition seems to be fulfilled.

If this theory is correct, the machines affected so far will definitely need a new bootcode. NewRPL would also need some adjustment as it cannot fit into the flash memory anyway.

By the way, if someone manages to un-brick one of the victims, could you fork over a copy of the bootcode as well? x49gp has the 49g+ and 50g bootcodes (or at least one version each, if there were multiple versions over the models' lifetimes), but no others. I was looking into adding support for 39/40 emulation, and even though the 49/50 bootcode might just do the trick, it'd be nicer to have the matching one.

I did not check this but I believe you are correct, the firmware is not "close" to full, it's already over with the latest updates.
You are absolutely right, 1024-16 = 1008 KB would be the maximum usable and the ROM is already over. I suggest people not install this ROM on the 39gs. I'll have to see if some code can be eliminated to reduce space, but I think the bootloader may not check and yes, the flash appears repeatedly in the address space, so that is likely the cause of the bootloader overwrite. I'll remove the link for the time being.


RE: newRPL - build 1255 released! [official and unofficial] - bzoom - 06-06-2019 04:44 AM

I managed to read first 4 4kB sectors from my bricked 39gs.
First 3 were wiped with FF value, 4th had similar but not identical content as 50g bootloader from
x49gp. Same strings but with some offset and s/n at the end.

Still problem with writing flash, causes error, write protect? And do not have wiped part of 39gs bootloader code.


RE: newRPL - build 1255 released! [official and unofficial] - 3298 - 06-06-2019 11:28 AM

Okay, so the offset means your 39gs probably had a different (newer?) version of the bootcode, but at least not a totally different one (kind of expected, to be honest). Of course I can't tell if the differences included something for the slightly different hardware configuration, but I think you could try just taking the 50g bootcode from x49gp and writing that onto the flash. I mean, what can go wrong that makes the situation worse than it is now?
Since the necessary part of the boot sector miraculously survived, you could even preserve the device's serial number (the last few bytes of the boot sector) by copying it over into the replacement boot sector. You'll recognize it, in x49gp it's the ASCII string "DEA0000001" for the 50g bootcode or "DE00000001" for the 49g+ one.

About writing to the flash, did you follow the normal flash-writing procedure consisting of a sequence of specific bytes written to specific offsets? If not, check out flash.c from the x49gp sources for details, specifically the function flash_put_halfword.


RE: newRPL - build 1255 released! [official and unofficial] - Martin Hepperle - 06-06-2019 12:07 PM

(06-05-2019 01:04 PM)rprosperi Wrote:  Another idea is to get a 49g+ for your host platform. They are MUCH cheaper than 50g's but have the correct keyboard, and much more memory. The 39gs has a smaller ROM capacity than the 49g+/50g, and Claudio has warned that the 39gs ROM capacity is nearly full now and soon will no longer be able to load the newRPL image.
Yes, maybe this is a better solution than to fiddle with a overlay and stickers etc.
Martin


RE: newRPL - build 1255 released! [official and unofficial] - Nigel (UK) - 06-06-2019 02:51 PM

(06-06-2019 12:07 PM)Martin Hepperle Wrote:  
(06-05-2019 01:04 PM)rprosperi Wrote:  Another idea is to get a 49g+ for your host platform. They are MUCH cheaper than 50g's but have the correct keyboard, and much more memory. The 39gs has a smaller ROM capacity than the 49g+/50g, and Claudio has warned that the 39gs ROM capacity is nearly full now and soon will no longer be able to load the newRPL image.
Yes, maybe this is a better solution than to fiddle with a overlay and stickers etc.
Martin
Note that (much earlier in the newRPL development process) I found that the 49g+ drew a large current (several tens of mA) even when the calculator was turned off. I haven't checked this recently so I'm not sure if the problem was ever solved but it is something to bear in mind.

Is anyone currently using a 49g+ flashed with newRPL without the battery drain problem?

Nigel (UK)


RE: newRPL - build 1255 released! [official and unofficial] - Claudio L. - 06-07-2019 02:03 AM

(06-06-2019 11:28 AM)3298 Wrote:  Okay, so the offset means your 39gs probably had a different (newer?) version of the bootcode, but at least not a totally different one (kind of expected, to be honest). Of course I can't tell if the differences included something for the slightly different hardware configuration, but I think you could try just taking the 50g bootcode from x49gp and writing that onto the flash. I mean, what can go wrong that makes the situation worse than it is now?
Since the necessary part of the boot sector miraculously survived, you could even preserve the device's serial number (the last few bytes of the boot sector) by copying it over into the replacement boot sector. You'll recognize it, in x49gp it's the ASCII string "DEA0000001" for the 50g bootcode or "DE00000001" for the 49g+ one.

About writing to the flash, did you follow the normal flash-writing procedure consisting of a sequence of specific bytes written to specific offsets? If not, check out flash.c from the x49gp sources for details, specifically the function flash_put_halfword.

As far as flashing the ROM, using the bootloader from a 50g should work. The only difference is it may offer you to flash from SD card which is not populated on the board, just don't use that option. The second difference is the 39 expects a different string at 0x4000 (beginning of the ROM file) than the 50g. To flash a ROM using the 50g bootloader you'd have to hex edit the ROM file and change that string manually to match the 50g string, other than that it should work perfectly, the hardware is the same save for the RAM and ROM sizes.

Also, if anyone has a working 39 with an older version of newRPL, it's very easy to dump the ROM doing:

Code:

<< #0h #3FFCh FOR K K PEEK 4 STEP #1000h ->LIST >>

Please do this and share here.


RE: newRPL - build 1255 released! [official and unofficial] - Claudio L. - 06-07-2019 02:14 AM

(06-06-2019 04:44 AM)bzoom Wrote:  I managed to read first 4 4kB sectors from my bricked 39gs.
First 3 were wiped with FF value, 4th had similar but not identical content as 50g bootloader from
x49gp. Same strings but with some offset and s/n at the end.

Still problem with writing flash, causes error, write protect? And do not have wiped part of 39gs bootloader code.

There's no write protect (unfortunately, otherwise we would all have healthy bootloaders now). The flash chip is this one, check the docs to see if it's being detected and programmed properly. The chip is 16 bit addressed so when they say address 0x55h you need to double that in the ARM view. Other than that gotcha, writing is quite straightforward.


RE: newRPL - build 1255 released! [official and unofficial] - pidhash - 06-07-2019 12:39 PM

.I get this error when I try to compile using qtCreator in linux, someone could help to fix this ?

----

09:38:36: Running steps for project newrpl-fw...
09:38:37: Configuration unchanged, skipping qmake step.
09:38:37: Starting: "/usr/bin/make" -j2
arm-none-eabi-gcc -c -pipe -g -mtune=arm920t -mcpu=arm920t -mlittle-endian -fno-jump-tables -fomit-frame-pointer -fno-toplevel-reorder -msoft-float -Og -pipe -mthumb-interwork -nostdinc -DTARGET_50G -DNDEBUG -DNEWRPL_BUILDNUM= -I../newrpl_31_05_2019 -I. -I/usr/lib/gcc/arm-none-eabi/8.3.0/include -I../newrpl_31_05_2019/firmware/include -I../newrpl_31_05_2019/newrpl -isystem /usr/local/include -isystem /usr/include -I/usr/lib/qt/mkspecs/linux-g++ -o auto_version.o auto_version.c
In file included from auto_version.c:3:
../newrpl_31_05_2019/newrpl/libraries.h:378:40: error: expected expression before ')' token
#define MAKESINT(a) MKOPCODE(DECBINT,(a)&0x3ffff)
^
../newrpl_31_05_2019/newrpl/libraries.h:77:55: note: in definition of macro 'MKOPCODE'
#define MKOPCODE(lib,op) (WORD)((((lib)&0xFFF)<<20)|((op)&0x7FFFF))
^~
auto_version.c:6:67: note: in expansion of macro 'MAKESINT'
0x0088000F,0x01B80004,0x5277656E,0x42204C50,0x646C6975,0x00000020,MAKESINT(NEWRP​L_BUILDNUM),0xFFA72010,
^~~~~~~~
make: *** [Makefile:2983: auto_version.o] Error 1
09:38:41: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project newrpl-fw (kit: Desktop)
When executing step "Make"
09:38:42: Elapsed time: 00:05.


RE: newRPL - build 1255 released! [official and unofficial] - Gilles - 06-07-2019 02:45 PM

(06-04-2019 08:46 PM)Claudio L. Wrote:  
(06-04-2019 11:11 AM)Gilles Wrote:  Not a priority at all and I know that DOSUBS or MAP do the job. But it could be nice to have a kind of FOR IN syntax :

{ 1 2 3 4 7 9 } FORIN 'MyDigit' ... NEXT
or
{"Red" "Yellow" "Blue" } FORIN 'MyColor' ... NEXT
or why not :
"abcdefxyz" FORIN 'MyChar' .... NEXT

Perhaps FOR instead of FORIN would be sufficiant, as it depends of the type of the object before FOR

I like it as an alternative format for FOR. NEXT would simply advance in the list. Is there any use for STEP? Perhaps add the number to the index within the list, so you can skip backwards or more than one item forward. The loop ends whenever the index is out of bounds.

I thinked about STEP. It coud be something like this

{ 1 2 3 4 7 9 } FOR 'MyDigit' ... NEXT
'MyDigit' is 1 for the first loop, 2 for the next loop etc.

{ 1 2 3 4 7 9 } FOR 'MyDigits' ... 2 STEP
'MyDigits' is { 1 2 } for the fisrt loop and { 3 4 } for the second loop etc.

{ 1 { "a" "b"} 4 7 9 } FOR 'MyStuff' ... 2 STEP
'MyStuff' is { 1 {"a" "b"} } for the fisrt loop and { 4 7 } for the second loop etc.

I like this because you can't do this easily with DOSUBS (with dosub we get 1 2 and 2 3 and 3 4 etc...
For the last loop, the list may content less elements but it's not a problem.

Negative step could do the same beginning by the end of the list. In this case, perhaps { 7 9 } and {3 4 } is better than { 9 7 } and { 4 3 } ?

The keyword could be FOR or FOREACH.


RE: newRPL - build 1255 released! [official and unofficial] - Claudio L. - 06-07-2019 04:57 PM

(06-07-2019 02:45 PM)Gilles Wrote:  
(06-04-2019 08:46 PM)Claudio L. Wrote:  I like it as an alternative format for FOR. NEXT would simply advance in the list. Is there any use for STEP? Perhaps add the number to the index within the list, so you can skip backwards or more than one item forward. The loop ends whenever the index is out of bounds.

I thinked about STEP. It coud be something like this

{ 1 2 3 4 7 9 } FOR 'MyDigit' ... NEXT
'MyDigit' is 1 for the first loop, 2 for the next loop etc.

{ 1 2 3 4 7 9 } FOR 'MyDigits' ... 2 STEP
'MyDigits' is { 1 2 } for the fisrt loop and { 3 4 } for the second loop etc.

{ 1 { "a" "b"} 4 7 9 } FOR 'MyStuff' ... 2 STEP
'MyStuff' is { 1 {"a" "b"} } for the fisrt loop and { 4 7 } for the second loop etc.

I like this because you can't do this easily with DOSUBS (with dosub we get 1 2 and 2 3 and 3 4 etc...
For the last loop, the list may content less elements but it's not a problem.

Negative step could do the same beginning by the end of the list. In this case, perhaps { 7 9 } and {3 4 } is better than { 9 7 } and { 4 3 } ?

The keyword could be FOR or FOREACH.

Nice idea, unfortunately it's not doable. When FOREACH is executed, the quantity that STEP will receive on the stack is not known yet (and may vary throughout the loop) so how many elements do we assign on the first run? Also, creating intermediate lists is expensive.
The loop would save the list and index on a local unnamed variable, so we can just give it a name (@LIST, @INDEX perhaps?) that the user can use within the loop. We can assign the given variable the current single element, but the user can get any other elements from the list with GET as needed. Another option would be a command that gives you the next or previous element but it's more limited.
STEP would just add to the index.

Anoooother option is for FOREACH to accept a list of variables instead of a single one:

Code:
{ a b c d e f } FOREACH { I J } ... NEXT
In the syntax above, FOREACH will take n elements from the list and assign them to the variables in the list. NEXT would skip n places so the next run in the example I==c and J==d.
STEP would skip the given elements (1 STEP would make the next run be I==b J==c) and could even accept negative values.
Loop would end when there's not enough values left on the list to fill all variables.[/code]


RE: newRPL - build 1255 released! [official and unofficial] - Bernd Grubert - 06-07-2019 08:26 PM

(06-07-2019 02:03 AM)Claudio L. Wrote:  Please do this and share here.

Here is the list, generated with a 39GS.

Regards
Bernd


RE: newRPL - build 1255 released! [official and unofficial] - bzoom - 06-08-2019 07:04 AM

Finally some success!
[attachment=7366]

openocd has some support for sst39* flash chips but it either does not work or I just cannot configure it right. High level flash erase, write etc functions did not work.

I had to use low level erase and "word-program" sequences from datasheet (thank you 3298, Claudio for showing the light in darkness )
and generate a script calling my custom function 8192 times... not exactly a pretty solution but hey it worked Smile

Code:

proc write_word {ADDRESS VALUE} {
# word program
echo "writing address: $ADDRESS"
   mwh 0xaaaa 0x00aa
   mwh 0x5554 0x0055
   mwh 0xaaaa 0x00a0
   mwh $ADDRESS $VALUE
   sleep 10
}

Code:

write_word 0x0 0x0006
write_word 0x2 0xea00
write_word 0x4 0x003f
...
write_word 0x3ffa 0xff00
write_word 0x3ffc 0xffff
write_word 0x3ffe 0xffff


I used 50g bootloader, seems to work ok in 39's smaller display.
Happy to see that 39gs bootloader is also now available, thank you!


RE: newRPL - build 1255 released! [official and unofficial] - Gilles - 06-09-2019 12:10 PM

Claudio, did you think that a 'RETURN' command could be introduce in the future?
'return' exists in most langage and in PPL. The idea is to be able to exit a command/fonction at any time with the stack as it is, even in the middle of nested loops and IF/CASE.... I imagine this is not obvious because the program have to exit all and to deal with internal stuff in a proper way.

In fact, it could be seen as a kind of EXIT (wich is a advantage of newRPL vs RPL) but not only for a loop but for a full command/function. (or like a local KILL)

Usage case is :

Code:
a b START
 c d START
  MyStuff
  IF DidIgetIt? THEN MyResult RETURN END 
 NEXT
NEXT
OtherThings

Without RETURN and with EXIT you have to use a flag or a local variable and awfull things like :

Code:
1 CF
a b START
 c d START
  MyStuff
  IF DidIgetIt? THEN MyResult 1 SF EXIT END 
 NEXT
 IF 1 FS? THEN EXIT END
NEXT
IF 1 FS? THEN EXIT END
OtherThings



RE: newRPL - build 1255 released! [official and unofficial] - Claudio L. - 06-11-2019 12:17 PM

(06-07-2019 08:26 PM)Bernd Grubert Wrote:  
(06-07-2019 02:03 AM)Claudio L. Wrote:  Please do this and share here.

Here is the list, generated with a 39GS.

Regards
Bernd


Thank you, great contribution! Now we can restore the real boot loader.

(06-08-2019 07:04 AM)bzoom Wrote:  Finally some success!


openocd has some support for sst39* flash chips but it either does not work or I just cannot configure it right. High level flash erase, write etc functions did not work.

I had to use low level erase and "word-program" sequences from datasheet (thank you 3298, Claudio for showing the light in darkness )
and generate a script calling my custom function 8192 times... not exactly a pretty solution but hey it worked Smile

Code:

proc write_word {ADDRESS VALUE} {
# word program
echo "writing address: $ADDRESS"
   mwh 0xaaaa 0x00aa
   mwh 0x5554 0x0055
   mwh 0xaaaa 0x00a0
   mwh $ADDRESS $VALUE
   sleep 10
}

Code:

write_word 0x0 0x0006
write_word 0x2 0xea00
write_word 0x4 0x003f
...
write_word 0x3ffa 0xff00
write_word 0x3ffc 0xffff
write_word 0x3ffe 0xffff


I used 50g bootloader, seems to work ok in 39's smaller display.
Happy to see that 39gs bootloader is also now available, thank you!

Great! Looks like that's the road I'll need to take. Also, using an RPI I can get it to do other things, not just a JTAG dongle. Thanks again.


RE: newRPL - build 1255 released! [official and unofficial] - Claudio L. - 06-11-2019 12:25 PM

(06-07-2019 12:39 PM)pidhash Wrote:  .I get this error when I try to compile using qtCreator in linux, someone could help to fix this ?

----

09:38:36: Running steps for project newrpl-fw...
09:38:37: Configuration unchanged, skipping qmake step.
09:38:37: Starting: "/usr/bin/make" -j2
arm-none-eabi-gcc -c -pipe -g -mtune=arm920t -mcpu=arm920t -mlittle-endian -fno-jump-tables -fomit-frame-pointer -fno-toplevel-reorder -msoft-float -Og -pipe -mthumb-interwork -nostdinc -DTARGET_50G -DNDEBUG -DNEWRPL_BUILDNUM= -I../newrpl_31_05_2019 -I. -I/usr/lib/gcc/arm-none-eabi/8.3.0/include -I../newrpl_31_05_2019/firmware/include -I../newrpl_31_05_2019/newrpl -isystem /usr/local/include -isystem /usr/include -I/usr/lib/qt/mkspecs/linux-g++ -o auto_version.o auto_version.c
In file included from auto_version.c:3:
../newrpl_31_05_2019/newrpl/libraries.h:378:40: error: expected expression before ')' token
#define MAKESINT(a) MKOPCODE(DECBINT,(a)&0x3ffff)
^
../newrpl_31_05_2019/newrpl/libraries.h:77:55: note: in definition of macro 'MKOPCODE'
#define MKOPCODE(lib,op) (WORD)((((lib)&0xFFF)<<20)|((op)&0x7FFFF))
^~
auto_version.c:6:67: note: in expansion of macro 'MAKESINT'
0x0088000F,0x01B80004,0x5277656E,0x42204C50,0x646C6975,0x00000020,MAKESINT(NEWRP​L_BUILDNUM),0xFFA72010,
^~~~~~~~
make: *** [Makefile:2983: auto_version.o] Error 1
09:38:41: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project newrpl-fw (kit: Desktop)
When executing step "Make"
09:38:42: Elapsed time: 00:05.

Your problem is here:
DNDEBUG -DNEWRPL_BUILDNUM=

There's no version number, which means qmake wasn't able to run the git command, check your path, you may need to add the directory in the project build environment. Also, make sure you use git clone, not just checkout. The version number is the number of commits so you need a full repository.


RE: newRPL - build 1255 released! [official and unofficial] - Claudio L. - 06-11-2019 12:42 PM

(06-09-2019 12:10 PM)Gilles Wrote:  Claudio, did you think that a 'RETURN' command could be introduce in the future?
'return' exists in most langage and in PPL. The idea is to be able to exit a command/fonction at any time with the stack as it is, even in the middle of nested loops and IF/CASE.... I imagine this is not obvious because the program have to exit all and to deal with internal stuff in a proper way.

In fact, it could be seen as a kind of EXIT (wich is a advantage of newRPL vs RPL) but not only for a loop but for a full command/function. (or like a local KILL)

Usage case is :

Code:
a b START
 c d START
  MyStuff
  IF DidIgetIt? THEN MyResult RETURN END 
 NEXT
NEXT
OtherThings

Without RETURN and with EXIT you have to use a flag or a local variable and awfull things like :

Code:
1 CF
a b START
 c d START
  MyStuff
  IF DidIgetIt? THEN MyResult 1 SF EXIT END 
 NEXT
 IF 1 FS? THEN EXIT END
NEXT
IF 1 FS? THEN EXIT END
OtherThings

EXIT will also return from the current program but it can only exit one program at a time. RPL has no function markers so there is no way to know how many secondaries RETURN is supposed to exit:

Code:

<<
 <<
 <<
 << mycode RETURN >>
@ Do we return here? Same as EXIT
>>
@ Or here?
>>
@ why not here?
>>
@ Is this the end of the function?



RE: newRPL - build 1255 released! [official and unofficial] - Gilles - 06-11-2019 06:51 PM

(06-11-2019 12:42 PM)Claudio L. Wrote:  EXIT will also return from the current program but it can only exit one program at a time. RPL has no function markers so there is no way to know how many secondaries RETURN is supposed to exit (…)
Quote:EXIT will also return from the current program but it can only exit one program at a time.

I'm not sure to understand your point. Perhaps I missed or misunderstand something. I thought that EXIT was something like BREAK in PPL, and my suggestion for RETURN was something like the RETURN in PPL.
For me EXIT dont return from the current program but exit the current loop (Or perhaps behind the scene a loop is a program in newRPL ?).
The idea of RETURN is different : stop the program (the subprogram) here and returns the stack "as it is" :

Exemple

Code:
«
 1 9 FOR 'a'
  1 9 FOR 'b'
   IF  a b + 4 == THEN a b RETURN END
  NEXT
 NEXT
»

-> 1 3

'a' loop is just executed once
'b' loop 3 times

But with EXIT

Code:
«
 1 9 FOR 'a'
  1 9 FOR 'b'
   IF  a b 4 + == THEN a b EXIT END
  NEXT
 NEXT
»
-> 1 3 2 2 3 1

The inner loop stops each time the condtion is true
The outer loop is executed 10 times


RE: newRPL - build 1255 released! [official and unofficial] - Claudio L. - 06-11-2019 10:59 PM

(06-11-2019 06:51 PM)Gilles Wrote:  
(06-11-2019 12:42 PM)Claudio L. Wrote:  EXIT will also return from the current program but it can only exit one program at a time. RPL has no function markers so there is no way to know how many secondaries RETURN is supposed to exit (…)
Quote:EXIT will also return from the current program but it can only exit one program at a time.

I'm not sure to understand your point. Perhaps I missed or misunderstand something. I thought that EXIT was something like BREAK in PPL, and my suggestion for RETURN was something like the RETURN in PPL.
For me EXIT dont return from the current program but exit the current loop (Or perhaps behind the scene a loop is a program in newRPL ?).
The idea of RETURN is different : stop the program (the subprogram) here and returns the stack "as it is" :

Exemple

Code:
«
 1 9 FOR 'a'
  1 9 FOR 'b'
   IF  a b + 4 == THEN a b RETURN END
  NEXT
 NEXT
»

-> 1 3

'a' loop is just executed once
'b' loop 3 times

But with EXIT

Code:
«
 1 9 FOR 'a'
  1 9 FOR 'b'
   IF  a b 4 + == THEN a b EXIT END
  NEXT
 NEXT
»
-> 1 3 2 2 3 1

The inner loop stops each time the condtion is true
The outer loop is executed 10 times

A program (secondary) during runtime is just an address pushed to the return stack. A loop is... also just an address pushed to the return stack. In my example I used all secondaries but it's all the same. If I wanted to distinguish them I'd have to do something special to "mark" which positions in the return stack are secondaries. I'll have to think if that is possible and how to implement it. EXIT simply pops that return address from the return stack and cleans up local vars as needed, but doesn't really know what exactly it is exiting. RETURN would have to basically EXIT multiple times until it (somehow) knows the next return address is outside the secondary.