Hallo!
Da jeder einen anderen Kenntnisstand hat, will ich einfach einmal von vorne anfangen 
 
Das RAM unter dem OS kann man genauso wie das RAM unterm BASIC einfach über PORTB einschalten, indem man den ROM-Chip abschaltet.
Es ist somit keinerlei Hexenwerk das RAM unterm OS zu nutzen... 
Jedoch wird der ATARI sich aufhängen, wenn man einfach das OS abschaltet, da der ATARI einen Non Maskable Interrupt (NMI) und einen Maskable Interrupt (IRQ) besitzt und diese ohne dem OS ins Nirvana verzweigen und somit den ATARI abstürzen lassen.
Was sind das für Interrupts?
Der NMI kommt ausschließlich vom ANTIC. Der ANTIC signalisiert über NMIEN, ob es durch einen VBI oder DLI ausgelöst wurde.
Der IRQ kommt vom POKEY und vom PIA. Man kann über IRQST des POKEY oder PACTL des PIA auslesen aus welchem Grund ein IRQ ausgelöst wurde.
Der POKEY ist u.a. für die Tastatur zuständig. Ein Tastendruck löst somit den IRQ aus.
Den IRQ kann man einfach per CPU-Flag unterdrücken. "SEI" lässt den IRQ unterdrücken. Mir "CLI" wird dieser wieder berücksichtigt.
Der NMI lässt sich nicht ausschalten... zu mindestens nicht CPU-seitig. Hier kann man aber dem ANTIC über NMIRES mitteilen, dass man keine IRQs wünscht.
Sind die beide IRQs abgeschaltet, kann man den RAM unterm ROM nutzen...
Nun ja, jetzt funktioniert aber nicht mehr viel. Keine Tastatureingaben, kein VBI und kein DLI. Für Spiele ist der VBI und DLI schon sehr wichtig. Und auch die Tastatur wird immer Mal wieder benötigt.
Wichtig zu wissen: Funktionstasten und Joystick benötigen keinen IRQ und funktionieren weiterhin.
Woher weiß eigentlich die CPU, was sie machen soll, wenn ein NMI oder IRQ auftritt?
An den Speicherstellen $FFFA/$FFFB steht die Sprungmarke für den NMI. An $FFFE/$FFFF die Sprungmarke für den IRQ. $FFFC/$FFFD ist beim ATARI 400/800 für den Reset zuständig.
Diese weisen beim eingeschaltetem OS auf die entsprechenden ROM-Routinen. Ist das OS abgeschaltet verweisen diese ins Nirvana.
Es gibt ein Assemblerlisting vom TurboBasic, wie dort mit dem Problem umgegangen wird. Es ist eigentlich sehr elegant.
TB hat zwei eigene Routinen für IRQ und NMI, die im Prinzip den Stack ein wenig manipulieren, damit das ROM zu der eigenen Routine zurück kehrt. Schaltet das OS ein, springt zur gewünschten ROM-Routine, schaltet das OS wieder aus und beendet den Interrupt sozusagen.
Wenn man dauerhaft den RAM unterm OS nutzen möchte, muss man entweder die TB-Routine nutzen, oder sich etwas Eigenes basteln.
Für mein Spiel benötige ich die meisten Schattenregister nicht, sondern nur ein paar (für mich) wichtige Funktionen des System-VBI. Deshalb habe ich mir aus dem OS die interessanten Funktionen in eine eigene Routine kopiert:
Code: Alles auswählen
; --- MADS Assembler-Routine
		.PROC MyNMI
		BIT NMIST		; Prüfen ob ein DLI ausgelöst wurde
         	BPL @+
         	JMP (VDSLST)		; Wenn ja, dann ab in die DLI Routine
@         	PHR
         			
		INC RTCLOK+2		; Systemtimer weiterlaufen lassen
		BNE @+
		INC RTCLOK+1
		BNE @+
		INC RTCLOK
@		LDA #$00
		STA SRTIMR
		MVA CHBAS  CHBASE	; Zeichensatz Schattenregister umkopieren
		MWA SDLSTL DLISTL	; DLI-Schattenregister umkopieren
		MWA SDMCTL DMACTL	; DMA-Kontroll-Schattenregister umkopieren
		LDA PORTA		; Joystick Port A ist Stick 0 & 1
		LSR			; Diese trennen und in die passenden 
		LSR			; Schattenregister bringen
		LSR
		LSR
		STA STICK1
		LDA PORTA
		AND #$0F
		STA STICK0
		LDA TRIG0		; Feuerknopf ebenfalls im jeweiligen
		STA STRIG0		; Schattenregister kopieren
		LDA TRIG1
		STA STRIG1
		LDX #$03		; Die einzelnen Paddles in die Schattenregister
@		LDA POT0,X		; umkopieren
		STA PADDL0,X
		DEX
		BPL @-
		
		PLR
		RTI
		.ENDP
Welchen Vorteil bringt mir dieses Vorgehen? Ich spare ein wenig Rechenzeit im VBI und kann damit mehr eigenen Programmcode im "nichtsichtbaren" Bereich ausführen lassen.
Den IRQ brauche ich größtenteils nicht und kann diesen per SEI abschalten. Aber sollte man doch z.B. die Tastatur nutzen wollen, kann man einfach die Routine des TurboBasics nehmen (leicht abgewandelt):
Code: Alles auswählen
; --- MADS Assembler-Routine
		.PROC MyIRQ
		PHA			; Akku sichern
         	LDA #>Exit		; Eigene Exit-Routine in den Stack schreiben
         	PHA
         	LDA #<Exit
         	PHA
         	PHP			; Prozessorstatus auf den Stack (für RTI)
         	INC PORTB		; OS-ROM anschalten (wichtig OS-ROM muss vorher aus sein!)
         	JMP (VIMIRQ)		; Ins Betriebssystem springen
Exit		DEC PORTB		; OS-ROM wieder abschalten
         	PLA			; Akku holen
         	RTI  			; und zurück
         	.ENDP
Um die Sprungadressen an $FFFA-$FFFF sicher setzen zu können, sollte man vorher kurz die Interrupts abschalten:
Code: Alles auswählen
; --- MADS Assembler-Routine
		SEI				; IRQ und VBI deaktivieren
		LDA #0
		STA NMIEN
		LDA PORTB			; OS-ROM und BASIC abschalten
 		AND #%11111100
 		ORA #%00000010 			; bit 0==0 OS-RAM bit 1==1 BASIC-RAM
 		STA PORTB
		LDX #0				; Neue IRQ-Sprungadressen setzen
POINTER_LOOP	LDA NEWPOINTER,X
 		STA $FFFA,X
 		INX
 		CPX #6
 		BNE POINTER_LOOP		
		
		LDA #NMIEN_VBI			; VBI und IRQ wieder aktivieren
		STA NMIEN
		CLI
		...
		...
NEWPOINTER	.WORD MyNMI
 		.WORD 0
 		.WORD MyIRQ		
		.ENDP
Jetzt kann man gefahrlos das OS dauerhaft im Programm abschalten, um den RAM nutzen zu können.
Je nachdem ist es ggf. sinnvoll den Zeichensatz aus dem ROM zu kopieren, sofern man keinen eigenen hat.
Grüße
Janko