1 Ostatnio edytowany przez mono (2009-11-09 18:13:07)

Interesuje mnie jak wywoływać procedury z romu kiedy go nie ma :D
Konkretnie chodzi o zagwarantowanie poprawnej obsługi przerwań przez system kiedy podnoszę sobie rom i operuję na ramie pod nim.
Założenia:
1. Nie satysfakcjonuje mnie blokada przerwań na czas operacji na ramie pod romem.
2. Chciałbym wywoływać przerwanie z romu przez jmp ($fffe) zakończone oczywiście przez rti.
Czy poniższy kod zadziała poprawnie? Na początek irq:

  ;ustawiamy wektory obslugi przerwan w ramie pod romem
  sei
  lda #0
  sta irqen
  lda #%11111110
  sta portb
  ldx <irqproc
  ldy >irqproc
  stx irqvec     ;$fffe
  sty irqvec+1 ;$ffff
  ;opuszczamy rom
  lda #%11111111
  sta portb
  lda #$c0
  sta irqen
  cli
  ...
  ;tu się dalej coś dzieje łącznie z podnoszeniem romu i opuszczaniem bez żadnej synchronizacji
  ...

irqproc equ *
  sta irq_a
  lda portb
  sta irq_pb
  lda #%11111111
  sta portb
  lda <irqret
  pha
  lda >irqret
  pha
  php
  lda irq_a
  jmp (irqvec)   ;$fffe
irqret equ *
  lda irq_pb
  sta portb
  lda irq_a
  rti

irq_a org *+1
irq_pb org *+1

Żeby spełnić założenia mój kod obsługi irq:
1. Zachowuje konfigurację pamięci.
2. Wstawia flagi i adres procedury odtwarzającej portb na stos.
3. Opuszcza rom i skacze pod $fffe.
Ponieważ flagi odkładane na stos mają celowo ustawiony znacznik I (php w procedurze przerwania - dodatkowo przenosi ono jeszcze flagę B dla przerwań brk) więc po wykonaniu rti z procedury systemowej (do której skaczemy jmp ($fffe)) powinniśmy z blokadą przerwań irq wrócić pod irqret i odtworzyć konfigurację pamięci - prawda? irq, które zdarzy się podczas obsługi nie powinno zostać odebrane, bo ma czekać na skasowanie flagi I. Akumulator w zasadzie mógłby być odtwarzany tylko w irqret, ale zakładam, że może być potrzebny userowi i stąd lda irq_a przed jmp ($fffe).

A teraz ta sama sztuczka tylko dla nmi :)
Jak wiadomo nmi nie można opóźnić (niezależnie od stanu flagi I zawsze jest wykonywana procedura obsługi przerwania) - da się go tylko zablokować, co mi kompletnie nie odpowiada, bo nie wiem w którym momencie przyjdzie mi skorzystać z ramu pod romem.
Czy poniższy kod zadziała poprawnie?

nmiproc equ *  
  sta nmi_a
  lda portb
  sta nmi_pb
  lda #%11111111
  sta portb
  lda <nmiret
  pha
  lda >nmiret
  pha
  php
  lda nmi_a
  jmp (nmivec)   ;$fffa
nmiret equ *
  lda nmi_pb
  sta portb
  lda nmi_a
  rti

nmi_a org *+1
nmi_pb org *+1

Implementacja się nie różni od tej dla irq, ale:
1. Mimo, że nmi mogą się przerywać, to w chwili kiedy włączymy rom mamy już obsługę nmi systemową i nie musimy nic przełączać (!) a więc specjalna obsługa potrzebna jest tylko kiedy rom jest podniesiony.
2. Sztuczka z php dalej przydaje się do odwlekania irq.
Najbardziej wrażliwy punkt to moment od przyjęcia przerwania do włączenia romu - 17 cykli. Jeśli vblk i dli nie będą interferować to chyba nie powinno być problemu?
Może ktoś z tym ma jakieś doświadczenia? Będzie to działać poprawnie?

Edit: Oczywiście całe cyklowanie dli pójdzie w kosz, ale na to już nic nie poradzę :(

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

2 Ostatnio edytowany przez drac030 (2009-11-09 18:18:02)

Nie wczytywałem się dokładnie, ale wygląda zdrowo. Zasadniczo status CPU odłożony na stosie przy wystąpieniu przerwania powinieneś jednak przekopiować na swoją ramkę stosu, bo inaczej, na przykład, SYSVBL będzie pomijało swoją drugą fazę (SEI ją blokuje).

SpartaDOS i TBXL stosują podobny sposób dostępu do OS-u spod OS-u od 25 lat, więc nie ma chyba powodów, żeby tobie się to miało nie udać :)

nmi      sec 
         .byte $24
irq      clc
         pha
         txa
         tsx
         pha
         lda portb
         pha
         ora #$01
         sta portb
         lda #>irts
         pha
         lda #<irts
         pha
         inx
         inx
         lda $0100,x
         pha
         bcc hop
         jmp (NMIVEC)
hop      jmp (IRQVEC)

irts     pla
         sta portb
         pla
         tax
         pla
         rti
KMK
? HEX$(6670358)

3 Ostatnio edytowany przez mono (2009-11-09 18:24:40)

Cieszę się, że ktoś to już wymyślił :D Znaczy, że idę dobrym torem.

Edit: Wielkie dzięki. Ta procedura jest lepsza, bo obsługa przerwania może być nawet w x-ram.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

4

Opisałem zasady używania OS-a przy wyłączonym ROM-ie w Atariki: http://atariki.krap.pl/index.php/Progra … nym_ROM-ie

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

5

super praktyczna wiedza, dzięki Mono że się nią dzielisz :)

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

6

Ku pamięci: adres powrotu kładziemy w kolejności starszy, młodszy, czyli jak napisał drac030, a nie Mono. Na stosie będzie little endian.

https://www.youtube.com/watch?v=jofNR_WkoCE