It is currently Mon Oct 20, 2014 5:28 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Thu Mar 08, 2012 11:29 pm 
Offline
User avatar
 WWW  Profile

Joined: Wed Jan 26, 2011 2:35 am
Posts: 141
I'm probably doing something obviously wrong with this code, but I just can't see it at the moment. I have written a loader program (Ophis assembly):

Code:
.org $1900

main:
    lda #255
    ldx #<code_block
    ldy #>code_block
    jsr $ffdd

    jmp $e00

code_block: .byte <code_file_name, >code_file_name
             .byte $00, $0e, $00, $00
             .byte $00, $0e, $00, $00
             .byte $0b, $00, $00, $00
             .byte $0b, $0e, $00, $00

code_file_name: .byte "CODE", 13


The main code itself is trivial:

Code:
.org $e00

main:
    lda #22
    jsr $ffee
    lda #5
    jsr $ffee
   
    rts


I can load the loader and main code in Elkulator after a reset and it works as expected: changing into MODE 5 and exiting with a Syntax Error - that's another issue...

However, if I press Break and try to load it again, the loader runs but the main code fails to execute correctly. It turns out that the addresses $e00 and $e01 (&e00 and &e01 in BBC BASIC notation) have been reset to 13 and 255, presumably because BASIC has overwritten them, but I guess that this happens after the code fails to run.

I'm curious as to why it should work after a reset, but not after a simple Break. What state am I inadvertently relying on to see this kind of behaviour?


Top
 
PostPosted: Fri Mar 09, 2012 7:52 pm 
Offline
User avatar
 Profile

Joined: Fri Apr 25, 2008 7:55 pm
Posts: 147
Quote:
ldx #<code_block
ldy #>code_block


I use the Beeb Lancs assembler (because I'm an old fart) but in that, the above would mean X = hi and Y = lo but for most OS calls, OSFILE included, the reverse is required for an 'XY' parameter block.

If this is the cause of the failure, the apparent <Break> versus Reset toggle may be because by coincidence, your erroneous 'YX' parameter block adopts zero or non-zero values in [YX+6] depending on initialisations. If this occurs, a non-zero value tells the OS to use the file's own load/exec address which may then allow the call to appear to have worked whereas a zero value will try and use the erroneous parameter block which will likely fail.

Could be complete ballcocks of course..... ;)

( $0D, $FF at PAGE is BASIC's initialisation of program workspace at <Break> or Reset and means that no program is yet present.)


Top
 
PostPosted: Fri Mar 09, 2012 9:46 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 7:02 pm
Posts: 273
In Ophis, < means low and > high.


Top
 
PostPosted: Fri Mar 09, 2012 10:44 pm 
Offline
 Profile

Joined: Fri Nov 07, 2008 2:28 pm
Posts: 65
I use the macros LO() and HI() to avoid confusion.

I see the logic behind < and > but using 'c' a lot with the opposite symbols >> and <<
I found it hard remembering which way was correct.

In fact I use macros a lot, so for your example I actually use:

LXYI code_block

-PJ


Top
 
PostPosted: Fri Mar 09, 2012 11:45 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 7:02 pm
Posts: 273
On a slightly more useful note, I've just tried your code in Elkulator with no problems. Which makes me think it's an obscure setup issue. What expansions / filesystems do you have active?


Top
 
PostPosted: Sat Mar 10, 2012 12:12 am 
Offline
User avatar
 WWW  Profile

Joined: Wed Jan 26, 2011 2:35 am
Posts: 141
Thanks for the suggestions so far. I did have some things turned on deep in the menus of Elkulator, but the problem remains, even with an unexpanded setup.

I've attached the problem files, so maybe they'll show the same problem on other people's systems.


Attachments:
File comment: Archive containing sources and UEF for diagnosis of an OSFILE problem.
LoadTest.zip [11.8 KiB]
Downloaded 9 times
Top
 
PostPosted: Sat Mar 10, 2012 2:02 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 7:02 pm
Posts: 273
Okay, after a reset CODE is being loaded at 1900 instead of E00 - not entirely sure what the root cause is (code_block is being modified by the OS while LOADER is being loaded). I'll look more into it in the morning.


Top
 
PostPosted: Sat Mar 10, 2012 10:44 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 7:02 pm
Posts: 273
Looks like you may have found a genuine OS bug. *RUN doesn't set the OSFILE control block pointer correctly, and the cassette file system variables aren't reset on break. So it keeps pointing to the block in LOADER, and overwrites it as soon as LOADER is loaded.

Solution - stick a BASIC program as the first thing to be loaded. Even

Code:
10*RUN LOADER


will set the variables up correctly.


Top
 
PostPosted: Sat Mar 10, 2012 1:36 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
FWIW I tried it on B-Em, as a BBC B and a Master, and haven't seen the problem you mention - it's always loading the main code at E00, whether or not I "rewind tape" between loads or not. I've also tried different types of resets between loads, including with *FX 200,2 and haven't seen anything strange.


Top
 
PostPosted: Sat Mar 10, 2012 4:21 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 7:02 pm
Posts: 273
It looks like this is an Electron-only bug.


Top
 
PostPosted: Sat Mar 10, 2012 5:55 pm 
Offline
User avatar
 WWW  Profile

Joined: Wed Jan 26, 2011 2:35 am
Posts: 141
I couldn't verify it with ElectrEm because I can't get that to run correctly on a relatively modern Ubuntu system. I'll try it on a real Electron at some point, hopefully this weekend.


Top
 
PostPosted: Sat Mar 10, 2012 7:17 pm 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 7:02 pm
Posts: 273
Electrem shows the same behaviour.


Top
 
PostPosted: Mon Mar 12, 2012 12:32 am 
Offline
User avatar
 WWW  Profile

Joined: Wed Jan 26, 2011 2:35 am
Posts: 141
And it fails on a real Electron, too! Interesting to find a bug like that after all these years. :shock:

Thanks for providing an explanation and workaround for it, Tom!


Top
 
PostPosted: Tue Apr 24, 2012 1:38 am 
Offline
 Profile

Joined: Sat Aug 22, 2009 7:45 pm
Posts: 34
TomW wrote:
*RUN doesn't set the OSFILE control block pointer correctly,
What OSFILE control block? *RUN isn't an OSFILE call, so there's no OSFILE control block for it to modify.
Quote:
However, if I press Break and try to load it again,
Try to load it or try to run it? Are you doing *RUN loader or *LOAD loader (enter) CALL &1900 ? Or even just CALL &190 without even reloading it?
Quote:
Okay, after a reset CODE is being loaded at 1900 instead of E00 - not entirely sure what the root cause is (code_block is being modified by the OS while LOADER is being loaded). I'll look more into it in the morning.
How are you re-exectuing the loader code? *RUN loader or CALL &1900? If CALL &1900 then you will be executing whatever happens to be left over in the memory there, along with a modified control block. The control block will hold the file information details of 'CODE' from when it was loaded the first time 'LOADER' was run. If 'CODE's load address is not &E00 then the first word in the control block will no longer be the &E00 that the source code specified. Also, if the 'CODE's execution address is not &E00 then the second word in the control block will not be the &E00 specified in the source code.
Do the load and execution addresses of 'CODE' happen to be &1900 ? In that case the OSFILE block will be left holding contents that instruct OSFILE to load a file to &1900, which is the action you are seeing.

Code:
Before calling OSFILE:
code_block: .byte <code_file_name, >code_file_name
             .byte $00, $0e, $00, $00 ; I want to load to &E00
             .byte $00, $0e, $00, $00 ; &00 = load to the address specified here
             .byte $0b, $00, $00, $00
             .byte $0b, $0e, $00, $00

After calling OSFILE:
code_block: .byte <code_file_name, >code_file_name
             .byte $00, $19, $00, $00 ; load address of file just loaded
             .byte $00, $19, $00, $00 ; exec address of file just loaded
             .byte $0b, $00, $00, $00 ; length of file just loaded
             .byte $00, $00, $00, $00 ; attributes of file just loaded

Resuse that OSFILE block without changing it:
code_block: .byte <code_file_name, >code_file_name
             .byte $00, $19, $00, $00 ; I want to load to &1900
             .byte $00, $19, $00, $00 ; &00 = load to address specified here
             .byte $0b, $00, $00, $00
             .byte $00, $00, $00, $00


Top
 
PostPosted: Tue Apr 24, 2012 9:05 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 7:02 pm
Posts: 273
jgharston wrote:
What OSFILE control block? *RUN isn't an OSFILE call, so there's no OSFILE control block for it to modify.


While you are technically correct, the routine *RUN calls to load the file (at $f1c4 on OS 1.2, can't remember where it is on Electron OS 1.0) does attempt to store load/exec/length to an OSFILE control block (at $f232 on OS 1.2). The Electron OS does not set a pointer for this routine during reset, meaning it can corrupt memory (in this case the OSFILE control block in loader). OS 1.2 does.

Quote:
*RUN loader[/b] or CALL &1900?


*RUN. I'm not a complete idiot. I have verified that the Electron OS is overwriting the OSFILE control block in loader at load time using Elkulator's debugger.


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

All times are UTC [ DST ]


Who is online

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