Using overlay memory: how, tips and possibility for direct save/load

Since we do not have native C compilers on the Oric, this forum will be mostly be used by people using CC65 or the OSDK. But any general C related post will be welcome !
User avatar
xahmol
Flight Lieutenant
Posts: 375
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: Using overlay memory: how, tips and possibility for direct save/load

Post by xahmol »

iss wrote: Wed Jun 29, 2022 11:53 am.
Good news for Sedoric I/O - at $4FD is the result code from last operation: if it's 0 (zero) - no error.
Saw that, but that does not help much if SEDORIC first throws you to BASiC on e.g. a file not found. C code can not recover from that (or do I miss something?)
Ideal would be to hijack ERRGOTO in a way.

Also, the SEARCH command is interesting before you save a file to see if an existing one exists , so you can ask the user if overwrite is OK.
In BASIC, this returns a 0 or 1 value on the variable EF. Was wondering: will setting that variable be destructive for C code as of course that EF var8able is stored somewhere? But also: would it be possible to read that variable from C code?
Because that would enable a File exists dialogue (that I do have in my Commodore targets).
Looking at the SEDORIC code for SEARCH, I could of course just patch that command again to store it at a memory location instead of EF:

Code: Select all

E608 A9 01 LDA #01 A = #01 (pour "trouvé")
E60A 4C D5 D7 JMP D7D5 et dans les deux cas, continue en D7D5 où la variable EF (Existing File) reçoit A (0 si "non trouvé",1 si "trouvé"). Pour le traitement logique du résultat de la recherche, il faudra donc demander IF -EF THEN... et non IF EF THEN...
and patch the jump to D7D5 with a jump to an own handler.
User avatar
xahmol
Flight Lieutenant
Posts: 375
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: Using overlay memory: how, tips and possibility for direct save/load

Post by xahmol »

Progress: managed to reroute the SEDORIC output to screen by indeed patching.

Started with a small Proof of Concept to reroute output to the $9000 memory area, and that works! Needed that to exactly see the output steam format.
Schermafbeelding 2022-06-29 152435.png
Code used:

Code: Select all

DOSROM				=	$04F2			; Call to function to disable/enable SEDORIC RAM
_DOSERROR			=	$04FD			; Disk error address
SED_PRINTCHAR		=	$D20F			; SEDORIC print character patch address
SED_XROM			=	$D5D8			; SEDORIC default jump address before patch

; Disk directory parser routines

; ------------------------------------------------------------------------------------------
_ORIC_DIRParse_start:
; Function to enable directory parser and reroute screen output while DIR is executed
; Input:	
; ------------------------------------------------------------------------------------------

	; Enable overlay RAM
	jsr	DOSROM							; Call function to toggle overlay RAM

	; Patch SEDORIC print character function
	lda #<ORIC_DIRParse_process			; Get low byte of parsing function
	sta SED_PRINTCHAR					; Store at patch address
	lda #>ORIC_DIRParse_process			; Get low byte of parsing function
	sta SED_PRINTCHAR+1					; Store at patch address
	lda #$60							; Load $60 for oppcode RTS
	sta SED_PRINTCHAR+2					; Store RTS at patch location

	; Disable overlay RAM
	jsr	DOSROM							; Call function to toggle overlay RAM

	lda #$00
	sta dirparse_automodify+1
	lda #$90
	sta dirparse_automodify+2

	rts

; ------------------------------------------------------------------------------------------
_ORIC_DIRParse_end:
; Function to disable directory parser and reroute screen output while DIR is executed
; Input:	
; ------------------------------------------------------------------------------------------

	; Enable overlay RAM
	jsr	DOSROM							; Call function to toggle overlay RAM

	; Patch SEDORIC print character function
	lda #<SED_XROM						; Get low byte of parsing function
	sta SED_PRINTCHAR					; Store at patch address
	lda #>SED_XROM						; Get low byte of parsing function
	sta SED_PRINTCHAR+1					; Store at patch address
	lda #$12							; Load original value
	sta SED_PRINTCHAR+2					; Store RTS at patch location

	; Disable overlay RAM
	jsr	DOSROM							; Call function to toggle overlay RAM

	rts

; ------------------------------------------------------------------------------------------
ORIC_DIRParse_process:
; Function to intercept the system char to screen routine
; Input:	Parses inout character stream via the X register
; ------------------------------------------------------------------------------------------

dirparse_automodify:
	sta $9000
	inc dirparse_automodify+1
	bne dirparseend
	inc dirparse_automodify+2

dirparseend:
	; Jump to XROM routine to return to SEDORIC gracefully
	jsr SED_XROM						; Jump to XROM routine
	.byte $10,$cd,$10,$cd				; Data for XROM

	rts
So, from here, a DIR parser should not be difficult anymore if I take only disks with this specific DIR layout as requirement.

(PS: Quickly noted that in the parser function, the use of zero page variables is to avoided, as the program went completely crazy ;- Apparently SEDORIC uses the same ZP addresses, but safeguards those on entering SEDORIC functions to restore afterwards)
Last edited by xahmol on Wed Jun 29, 2022 2:38 pm, edited 1 time in total.
User avatar
Dbug
Site Admin
Posts: 4082
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: Using overlay memory: how, tips and possibility for direct save/load

Post by Dbug »

xahmol wrote: Wed Jun 29, 2022 12:08 pm Saw that, but that does not help much if SEDORIC first throws you to BASiC on e.g. a file not found. C code can not recover from that (or do I miss something?)
Ideal would be to hijack ERRGOTO in a way.
Have you found out how it gets back to BASIC?
Technically you can redirect the "Ready" prompt to call some code, it's often used as a protection in BASIC programs to call the reset routine when going back to the prompt:

DOKE(#1B,DEEK(#FFFC))

Technically you could replace this vector by a way to recover from errors, but I don't know what the status of the stack, etc... would be.

I guess technically the Sedoric/Basic wrapper could do something like having a small function designed to restore the stack pointer value and jmp to the end of the Sedoric function caller, and before calling Sedoric modify #1B-1C to point to this function and set the right stack value to restore to.

If the code does not crash, nothing happen, if it does crash, it would auto-jump to the crash handler, restore the stack, and jump back to continue running the code.
User avatar
xahmol
Flight Lieutenant
Posts: 375
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: Using overlay memory: how, tips and possibility for direct save/load

Post by xahmol »

Dbug wrote: Wed Jun 29, 2022 2:38 pm Have you found out how it gets back to BASIC?
Well, see for example here (page 187):

Code: Select all

Affiche le message "DISP_TYPE_MISMATCH"
Puis réinitialise la pile, affiche "_ERROR" et retourne au "Ready"
D16F- A9 A3 LDA #A3 pour le message "DISP_TYPE_MISMATCH_ERROR" (bogue: LDX)
D171- 20 D8 D5 JSR D5D8 XROM exécute à partir de la RAM une routine ROM
D174- 85 C4 7E C4 adresse ROM 1.0 adresse ROM 1.1 (affiche le message)
So, apparently it jumps to C47E, which is indeed the standard Oric Atmos ROM routine to print error messages (apart from skipping the first LDX) and return to BASIC (and indeed seems to clear stack and everything):

Code: Select all

PRINTERROR
$C47C	A2 4D                    	LDX   #$4D                              	PRINT ERROR MESSAGES
$C47E	20 2F C8                 	JSR   $C82F                             	Reset output to screen.
$C481	46 2E                    	LSR   $2E                               	Reset CTRL O.
$C483	20 F0 CB                 	JSR   $CBF0                             	Move to start of next line.
$C486	20 D7 CC                 	JSR   $CCD7                             	Print "?" on screen.
$C489	BD A8 C2                 	LDA   $C2A8,X                           	Print error message on screen
$C48C	48                       	PHA                                     	until last char which has bit
$C48D	29 7F                    	AND   #$7F                              	7 set. X holds initial offset
$C48F	20 D9 CC                 	JSR   $CCD9                             	into error table at start of
$C492	E8                       	INX                                     	routine.
$C493	68                       	PLA
$C494	10 F3                    	BPL   $C489
$C496	20 26 C7                 	JSR   $C726                             	Reset 6502 stack etc.
$C499	A9 A6                    	LDA   #$A6                              	Print "ERROR" after the
$C49B	A0 C3                    	LDY   #$C3                              	message.
$C49D	20 B0 CC                 	JSR   $CCB0
$C4A0	A4 A9                    	LDY   $A9                               	If high byte of line number
$C4A2	C8                       	INY                                     	is #FF then the computer is in
$C4A3	F0 03                    	BEQ   $C4A8                             	immediate mode (not program).
$C4A5	20 BA E0                 	JSR   $E0BA                             	Print "IN (line number>"


BACKTOBASIC
$C4A8	4E 52 02                 	LSR   $0252                             	RESTART BASIC
$C4AB	46 2E                    	LSR   $2E                               	Clear pending ELSE, CTRL O
$C4AD	4E F2 02                 	LSR   $02F2                             	and LIST/EDIT flags.
$C4B0	A9 B2                    	LDA   #$B2
$C4B2	A0 C3                    	LDY   #$C3
$C4B4	20 1A 00                 	JSR   $001A                             	Print "Ready"
See only in the SEDORIC code that it does not use just one single routine or ROM entry point, references to "retourne au Ready" are all over the place, using also different ROM entry points.
For example, here entry point in ROM at C4A0, so few lines further, probably becasue SEDORIC already printed its own error message (p 187):

Code: Select all

Retourne au Ready après affichage d'un message d'erreur
D154- 20 D8 D5 JSR D5D8 XROM exécute à partir de la RAM une routine ROM
D157- AD C4 A0 C4 adresse ROM 1.0 adresse ROM 1.1
D15B- 60 RTS
So have to try, that one on p 187 seems to be the most promising entry point for patching, but there it is already to late to have SEDORIC print its own error message. Think then I have to find wherever it actually prints those error messages and patch already there.

Edit: Apparently, it prints those messages here:

Code: Select all

D391- 20 2A D6 JSR D62A XAFCAR affiche le caractère ASCII contenu dans A
So maybe could patch there to save the error message to a string instead of printing it, and then patch the jump to BASIC one.

(BTW: Following the French of 'SEDORIC 3.0 à NU' is more manageable than I thought)
User avatar
iss
Wing Commander
Posts: 1466
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: Using overlay memory: how, tips and possibility for direct save/load

Post by iss »

Intercepting $1B,$1C is exactly what libbasic does (stack sanity included) ;).
Post Reply