Does anyone have a small 'un-new' ML routine for the VIC, preferably relocatable? Ones for the C64 should work, too. It should operate with any BASIC start address.
Compute! Issue 37 - June 1983 had one, but I haven't been able to find either the issue or the program online.
I found reference to one that you load into the casette buffer so it doesn't overwrite your BASIC program, then SYS to, but not the routine or program itself.
Un-new routine for the VIC?
Moderator: Moderators
- Schema
- factor
- Posts: 1430
- Joined: Tue Mar 23, 2004 7:07 am
- Website: http://www.jammingsignal.com
- Location: Toronto, Ontario
As far as I know, you can only salvage a newly removed program by restoring the pointer to first line:
SOB=start of Basic
LB=low byte of first line pointer
HB=ditto high byte
POKE SOB+1,LB:POKE SOB+2,HB
Inspired by my previous post, I would try something like this:
Having that said, I have a few OLD listings I could look up and see if they manage to do something more advanced than the code above, which relies on that the program is not more damaged than the first pointer.
SOB=start of Basic
LB=low byte of first line pointer
HB=ditto high byte
POKE SOB+1,LB:POKE SOB+2,HB
Inspired by my previous post, I would try something like this:
Code: Select all
LDY #$01
LDA $2C ; requires SOB to be at $xx00, so first line on same page
STA ($2B),Y ; pointer at $2B/2C points to SOB+1
JSR $C533 ; relink program to fix LB
LDX $23
LDA $22
CLC
ADC #$02
BCC A
INX
A: STA $2D
STX $2E
JSR $C659
JMP ???? ; don't know where to return to READY prompt
Anders Carlsson
Re: Un-new routine for the VIC?
'new' just sets the first 2 bytes (the link address of the first line) to 0. You basically need to set it so it points to the next line, and fix the end addresses. Be sure to do clear afterwards.Schema wrote:Does anyone have a small 'un-new' ML routine for the VIC, preferably relocatable? Ones for the C64 should work, too. It should operate with any BASIC start address.
Trick: set it to anything and call the relinker to fix the link!
Code: Select all
1400 A0 01 LDY #$01
1402 98 TYA
1403 91 2B STA ($2B),Y ; store a non zero in the MSB of the first link addr
1405 20 33 C5 JSR $C533 ; relinker
1408 A5 22 LDA $22 ; set end of basic/start of variables to the address of the last '0' found + 2
140a 18 CLC
140b 69 02 ADC #$02
140d 85 2D STA $2D
140f A5 23 LDA $23
1411 69 00 ADC #$00
1413 85 2E STA $2E
1415 4C 5E C6 JMP $C65E ; CLR
You were fast!carlsson wrote:Having that said, I have a few OLD listings I could look up and see if they manage to do something more advanced than the code above, which relies on that the program is not more damaged than the first pointer.
I was a bit slower, but I did look it up, and my routine is shorter.
I'm a bit amused by how similar they are considering we didn't look at each others code.
- Schema
- factor
- Posts: 1430
- Joined: Tue Mar 23, 2004 7:07 am
- Website: http://www.jammingsignal.com
- Location: Toronto, Ontario
You guys are fast! I was wondering about the relinker and tried some tests, but was using the LSB, not the MSB.
This even works from BASIC:
POKE4098,1:SYS50483 <= One line UN-NEW
I guess the relinker doesn't fix the variable locations (since I see you're doing it manually in your code), so you don't dare re-run the program or assign any variables afterwards. But in an emergency, you could do this to rescue a program and save it.
FYI, it also works after a soft-reset.
This even works from BASIC:
POKE4098,1:SYS50483 <= One line UN-NEW
I guess the relinker doesn't fix the variable locations (since I see you're doing it manually in your code), so you don't dare re-run the program or assign any variables afterwards. But in an emergency, you could do this to rescue a program and save it.
FYI, it also works after a soft-reset.
Ah, I didn't realize the first line pointer can be set to anything non-zero. Does it mean that Basic would refuse to run in zero page, even if there was empty space?
If I had not posted in the other thread last week, I would not have known about the relinker routine. It is correct that the relinker does not fix the variable pointers, that is the other routine.
By the way, entering at C65E with the Z flag cleared (which in most cases the above LDA/ADC should end up as) seems to end up as an immediate RTS? I know it is the entry point for CLR, but it is preceeded by a syntax check that sets the Z flag, I believe. The entry at C659 will reset the pointer to next Basic byte. Entering at C660 will close all open files. Entering at C663 will only set the pointers.
Also notice that the stack pointer will be reset to $FA, so don't put any values on the stack and expect to retrieve them after calling the routine.
If I had not posted in the other thread last week, I would not have known about the relinker routine. It is correct that the relinker does not fix the variable pointers, that is the other routine.
By the way, entering at C65E with the Z flag cleared (which in most cases the above LDA/ADC should end up as) seems to end up as an immediate RTS? I know it is the entry point for CLR, but it is preceeded by a syntax check that sets the Z flag, I believe. The entry at C659 will reset the pointer to next Basic byte. Entering at C660 will close all open files. Entering at C663 will only set the pointers.
Also notice that the stack pointer will be reset to $FA, so don't put any values on the stack and expect to retrieve them after calling the routine.
Anders Carlsson
Yes. It also means that the end of the last line can be marked by $00, $xx, $00.carlsson wrote:Ah, I didn't realize the first line pointer can be set to anything non-zero. Does it mean that Basic would refuse to run in zero page, even if there was empty space?
You can use this to do a shorter sys-line. Just make $xx a valid instruction which you need, for example $A9, $00 which is LDA #$00.
You are correct! My bad.carlsson wrote:By the way, entering at C65E with the Z flag cleared (which in most cases the above LDA/ADC should end up as) seems to end up as an immediate RTS? I know it is the entry point for CLR, but it is preceeded by a syntax check that sets the Z flag, I believe. The entry at C659 will reset the pointer to next Basic byte. Entering at C660 will close all open files. Entering at C663 will only set the pointers.
$c659 like you wrote in your code is probably the best choice.
Also true, but the return adress is preserved, so you will return to where you came from.carlsson wrote:Also notice that the stack pointer will be reset to $FA, so don't put any values on the stack and expect to retrieve them after calling the routine.