Programowanie: Przerywanie długotrwałych operacji klawiszem BREAK
From Atariki
Wersja z dnia 15:43, 10 cze 2014 Mono (Dyskusja | wkład) (kosmetyka) ← Previous diff |
Wersja z dnia 21:40, 10 cze 2014 Mono (Dyskusja | wkład) (wartosc IRQSTAT) Next diff → |
||
Linia 46: | Linia 46: | ||
seq | seq | ||
rts | rts | ||
+ | dec IRQSTAT | ||
lda #$80 ;BREAK KEY ABORT | lda #$80 ;BREAK KEY ABORT | ||
- | sta IRQSTAT | ||
jmp U_FAIL | jmp U_FAIL | ||
- | Warto zauważyć, iż po wykryciu wciśnięcia klawisza BREAK przywracana jest wartość $80 w IRQSTAT. Ustawiana jest ona przez OS podczas normalnej pracy (podczas operacji SIO mogą się tam znaleźć kody błędów). | + | Warto zauważyć, iż po wykryciu wciśnięcia klawisza BREAK wstawiana jest wartość $FF do IRQSTAT. Ustawiana jest ona przez OS podczas normalnej pracy (procedury edytora ustawiają tam wartość $80 po obsłudze wciśnięcia klawisza BREAK, lub $88 po obsłudze wciśnięcia kombinacji klawiszy CTRL+3). |
Jest to o tyle istotne, że funkcje konsoli sprawdzają tę komórkę i również generują błąd wciśnięcia klawisza BREAK. Brak obsługi IRQSTAT spowodowałby nieoczekiwane wyrzucenie błędu przy pierwszej próbie użycia np. '''PRINTF''', '''PUTC''', itp. | Jest to o tyle istotne, że funkcje konsoli sprawdzają tę komórkę i również generują błąd wciśnięcia klawisza BREAK. Brak obsługi IRQSTAT spowodowałby nieoczekiwane wyrzucenie błędu przy pierwszej próbie użycia np. '''PRINTF''', '''PUTC''', itp. | ||
Wersja z dnia 21:40, 10 cze 2014
SpartaDOS X posiada mechanizmy pozwalające programiście elegancko obsługiwać sytuacje wyjątkowe. Służą do tego procedury opisane w 4 rozdziale podręcznika programowania p.t. "Obsługa błędów".
Zazwyczaj używa się ich przy przechwytywaniu sytuacji wyjątkowych występujących podczas operacji na plikach, jednakże można z powodzeniem wykorzystać ten mechanizm do generowania sytuacji wyjątkowych we własnych procesach.
Wystarczy ustawić własną obsługę błędu za pomocą U_SFAIL i z wnętrza własnej procedury wywołać fukcję U_FAIL z kodem błędu w akumulatorze:
protectedroutine: lda ?catchad ldx ?catchad+1 jsr U_SFAIL jsr routine jmp U_XFAIL ?catchad .dw catchroutine catchroutine: ... ;obsługujemy błąd rts ;a to procedura generująca błąd routine: ... ;coś robimy lda #ERROR ;i generujemy błąd jmp U_FAIL
W przypadku wygenerowania błędu funkcja U_FAIL przekazuje sterowanie natychmiast do procedury obsługi, a stan stosu odtwarzany jest tak, aby powrót nastąpił do procedury wywołującej kod zakładający pułapkę - w tym przypadku będzie to punkt wywołujący protectedroutine.
UWAGA! U_SFAIL w żaden sposób nie raportuje przepełnienia wewnętrznego stosu zarejestrowanych procedur obsługi błędów należy więc pamiętać, iż takich procedur obsługi może być maksymalnie 10.
OS w przypadku naciśnięcia klawisza BREAK powoduje wyzerowanie komórki IRQSTAT ($11). Można więc wykorzystując opisany wyżej mechanizm łatwo zaimplementować funkcjonalność przerywania dowolnego długotrwałego procesu za pomocą wciśnięcia klawisza BREAK.
W kodzie długotrwałej procedury należy co jakiś czas sprawdzać zawartość IRQSTAT i jeśli została wyzerowana rzucić błąd (np. BREAK KEY ABORT)
routine: ... jsr erroronbreak ... rts erroronbreak: lda IRQSTAT seq rts dec IRQSTAT lda #$80 ;BREAK KEY ABORT jmp U_FAIL
Warto zauważyć, iż po wykryciu wciśnięcia klawisza BREAK wstawiana jest wartość $FF do IRQSTAT. Ustawiana jest ona przez OS podczas normalnej pracy (procedury edytora ustawiają tam wartość $80 po obsłudze wciśnięcia klawisza BREAK, lub $88 po obsłudze wciśnięcia kombinacji klawiszy CTRL+3). Jest to o tyle istotne, że funkcje konsoli sprawdzają tę komórkę i również generują błąd wciśnięcia klawisza BREAK. Brak obsługi IRQSTAT spowodowałby nieoczekiwane wyrzucenie błędu przy pierwszej próbie użycia np. PRINTF, PUTC, itp.
Oczywiście ustawianie własnej pułapki przez U_SFAIL nie jest obowiązkowe. Wyjątek rzucony przez U_FAIL przechwyci w takiej sytuacji poprzednio zarejestrowana procedura lub w ostateczności systemowa procedura obsługi błędów.