Page 1 of 1

Basic <-> C data exchanges

Posted: Sun May 04, 2014 10:45 am
by Hialmar
I'm working with Maximus on his RPG.

I've rewritten some code in C (drawing a labyrinth in HIRES with the line assembler routines found on miniserve) and I need to exchange some data with the rest of the application which is coded in Basic.

After some thoughts here is what we have planned:
- First we load a Basic program from a Sedoric disk;
- From this Basic program you can either start other Basic programs (loading them from the Sedoric disk) or the C program;
- Then from any program you can start other Basic or C programs.

Therefore we need to exchange some data from program to program.
It contains basically the position and orientation in the labyrinth (3 bytes) and the characters data (about 400 bytes).

Currently Basic programs do the following:
- position and orientation are kept at #BFE0 and the two next addresses ;
- characters data are first written at #A000 (while in text mode obviously) and saved to disk ;
- the new program then get the small data from #BFE0, then loads the characters data and read them into arrays.

Is it safe to write data at #BFE0 and above (it's marked as reserved in the manual) ?
When we switch programs with a LOAD, does the HIRES memory get wiped (provided we are in text mode when we do that) ?
If it doesn't then I'm inclined to put everything there, switch programs and get everything from there before doing anything else in the new program (switching to HIRES for example).

Of course if you have better solutions I'm interested.

Oh and one last question, in order to load/save data from/to a Sedoric disk in C should I better use the assembler code found here:
http://forum.defence-force.org/viewtopic.php?f=4&t=222
or call Sedoric !LOAD with the sedoric function found in lib.h like this:
sedoric("!LOAD(\"TEAM.BIN\")");

Sorry for the length of my message and thank you for reading through here.

Re: Basic <-> C data exchanges

Posted: Sun May 04, 2014 11:12 am
by Dbug
Hialmar wrote:Therefore we need to exchange some data from program to program.
It contains basically the position and orientation in the labyrinth (3 bytes) and the characters data (about 400 bytes).
Ok, that does not sound bad :)
Hialmar wrote:Currently Basic programs do the following:
- position and orientation are kept at #BFE0 and the two next addresses ;
- characters data are first written at #A000 (while in text mode obviously) and saved to disk ;
- the new program then get the small data from #BFE0, then loads the characters data and read them into arrays.
Is it safe to write data at #BFE0 and above (it's marked as reserved in the manual) ?
Normally yes, the 20 bytes between the screen and the ROM are free to use, at least I did it and never had any problem, but then again I was not using Sedoric so I would advise you to do a quick test to make sure they don't get wiped.
Hialmar wrote:When we switch programs with a LOAD, does the HIRES memory get wiped (provided we are in text mode when we do that) ?
If it doesn't then I'm inclined to put everything there, switch programs and get everything from there before doing anything else in the new program (switching to HIRES for example).
I don't think the video memory get impacted when loading, as far as I know the only case of video memory corruption I can think of was on the ORIC 1 when doing a CLOAD in HIRES it will still try to display the "SEARCHING/FOUND/LOADING" messages... in the middle of what is not the HIRES screen.

There's an area of memory that people often forget: There are two character sets on the Oric, the STD and the ALT, and most people never use the ALT one, which gives you at least 986 more bytes free to use for whatever you want in TEXT and 1024 in HIRES (don't ask :) )

Now of course this memory moves when the screen switches between TEXT and HIRES, so you have to account for that
Hialmar wrote:Oh and one last question, in order to load/save data from/to a Sedoric disk in C should I better use the assembler code found here:
http://forum.defence-force.org/viewtopic.php?f=4&t=222
or call Sedoric !LOAD with the sedoric function found in lib.h like this:
sedoric("!LOAD(\"TEAM.BIN\")");
No idea, I never use Sedoric, and rarely BASIC

Re: Basic <-> C data exchanges

Posted: Sun May 04, 2014 2:09 pm
by Symoon
Hialmar wrote:Is it safe to write data at #BFE0 and above (it's marked as reserved in the manual) ?
As long as you don't use new Sedoric Basic commands (from memory, LINE and BOX), which use this space.
Check Sedoric à Nu, I wonder if other commands don't use it.

Anyway, it's worth a try, I don't think there are too many commands using this area.

Re: Basic <-> C data exchanges

Posted: Sun May 04, 2014 3:13 pm
by Hialmar
Ok thanks to both of you.

I will try the alternate characters zone.

I have tried using the sedoric C function but I have trouble linking with it so I will try the routines made by Symoon.

Re: Basic <-> C data exchanges

Posted: Sun May 04, 2014 4:06 pm
by Symoon
If you want more details, the routines were described in the CEO Mag for the 20th Oric anniversary from January 2003 (freely available).
Though be carfeul, Twilighte talked about a bug correction, which I can't remember - you'd better double check the 2003 routines with what Twilighte posted here in 2007.

Re: Basic <-> C data exchanges

Posted: Sun May 04, 2014 5:12 pm
by Hialmar
Ok thanks.

I'm a CEO member so I have access to every issue of the CEO mag so no problem there.

I have also found some interesting stuff in the annexes of "Sedoric à nu".

I'll post here what I find out so that other people can use it.

Re: Basic <-> C data exchanges

Posted: Sun May 04, 2014 8:40 pm
by Hialmar
Okay I have managed to have Sedoric I/O working.

Here is the ASM code :

Code: Select all


#define SwitchOutROM $04f2
#define SwitchInROM  $04f2

_DiscSave
.(
	sei ; disable interrupts
	ldy #0
	lda (sp),y ; Filename lo
	sta $e9
	iny
	lda (sp),y ; Filename hi
	sta $ea
  
	jsr SwitchOutROM ; enable OverlayRAM
	lda #$00 
	jsr $d454 ; verify filename and copy it to BUFNOM

	;Setup Areas 
	ldy #2
	lda (sp),y ;Start Address Lo 
	sta $c052 
	iny
	lda (sp),y ;Start Address Hi 
	sta $c053 
	iny
	lda (sp),y ;End Address Lo 
	sta $c054
	iny 
	lda (sp),y ;End Address Hi 
	sta $c055 
	
	lda #$00  
	sta $c04d ; 0 here means SAVEO !
	sta $c04e ; 0 here means no params
	lda #$40  ; file type - data and no auto
	sta $c051 
	jsr $de0b ; set LGSAL0 and call XSAVEB
	jsr SwitchInROM ; disable Overlay RAM
	cli ; re-enable interrupts
	lda $4fd ; Get result (low byte)
	ldx #0   ; Get result (high byte)
	rts 
.)


_DiscLoad
.(
	sei ; disable interrupts
	ldy #0
	lda (sp),y ; Filename lo
	sta $e9
	iny
	lda (sp),y ; Filename hi
	sta $ea
	;
	jsr SwitchOutROM ; enable OverlayRAM

	lda #00
	jsr $dff9  ; verify filename and load file
	jsr SwitchInROM ; disable OverlayRAM
	cli ; re-enable interrupts
	lda $4fd ; Get result (low byte)
	ldx #0   ; Get result (high byte)
	rts
.)

_Sedoric		; invoke a SEDORIC command using black magic
.(			    ; Watch it! I have reasons to believe this is broken
	ldy #$0         ; grab string pointer
	lda (sp),y
	sta tmp
	iny
	lda (sp),y
	sta tmp+1
	dey

sedoricloop1            ; copy the string to #35..#84
	lda (tmp),y
	sta $35,y
	iny
	ora #$0
	bne sedoricloop1
	lda #$0				; terminate with a 0
	sta $35,y

	sta $ea         ; update the line start pointer
	lda #$35;
	sta $e9

	jsr $00e2       ; get next token
	jmp ($02f5)     ; call the ! command handler
.)

_SwitchToCommand
.(
	ldy #$0         ; grab string pointer
	lda (sp),y
	sta tmp
	iny
	lda (sp),y
	sta tmp+1
	dey

sedoricloop2            ; copy the string to #35..#84
	lda (tmp),y
	sta $35,y
	iny
	ora #$0
	bne sedoricloop2
	lda #$0				; terminate with a 0
	sta $35,y
	
	ldx #$34
	ldy #$00
	
	jsr $c4bd ; call the interpreter
	rts  ; will never be called
.)
And the prototypes:

Code: Select all

extern char DiscSave(char * filename, char * pini, char * pend);
extern char DiscLoad(char * filename);
extern char Sedoric(char * command);
extern void SwitchToCommand(char * command);
The two first functions are Symoon's save and load functions.
The third one allows to execute a Sedoric command (like !DIR for example).
The fourth one (taken from Sedoric à nu) allows to execute another program (never returns to your code).

The only thing I changed is I added a terminating 0 in the keyboard buffer in Sedoric as I think you have to do that.

I also return $4fd at the end of DiscLoad even though I'm not sure it actually works. I'll check later.