HANDLER "A:"Także wszelkiego typu monitory dyskowe mają dosyć ograniczone zastosowanie. Przedstawiony na listingu nr 1 program jest próbą rozwiązania powyższego problemu. Tworzy on (w sposób podany w numerze 8/91 TA) urządzenie zewnętrzne o nazwie A:, pozwalające na uzyskanie dostępu do dowolnego sektora dysku. Forma handlera jest chyba najbardziej uniwersalną, pozwala bowiem na współpracę z większością programów użytkowych (choć program pomyślany jest przede wszystkim jako narzędzie wspomagające Basic). Dostęp do pojedynczego sektora uzyskujemy (z Basicu) przez wykonanie instrukcji OPEN #kanał,licz1,licz2,"A:nrsek/T" gdzie licz1 wybiera kierunek przekazywania danych (4 - odczyt, 8 - zapis), licz2 jest ignorowana, nrsek to numer żądanego sektora (dziesiętnie), rozszerzenie /T ma znaczenie przy instrukcji Close - o tym za moment. Numer sektora musi być liczbą, w innym wypadku zasygnalizowany zostanie błąd nr 255. Gęstość zapisu zostanie rozpoznana automatycznie (w przypadku formatu innego niż jeden z trzech standardowych zasygnalizowany będzie błąd 254). I jeszcze jedno: próba uzyskania dostępu do kilku sektorów Jednocześnie spowoduje błąd nr 161 (to ograniczenie istnieje głównie ze względów oszczędnościowych - każdy sektor wymaga 256 bajtowego bufora). Gdy operacja otwarcia kanału przebiegła pomyślnie - możemy już do woli odczytywać (GET/INPUT), lub zapisywać (PUT/PRINT) dane. Dostęp do sektorów jest sekwencyjny, tzn. odczytywane i zapisywane są one kolejno, oczywiście po opróżnieniu, bądź zapełnieniu bufora. Przekroczenie największego dozwolonego numeru sektora powoduje błąd nr 136 - EOF. Zamknięcia kanału dokonujemy oczywiście instrukcją CLOSE. W tym miejscu pora na wyjaśnienie tajemniczego rozszerzenia /T w nazwie pliku. Otóż przy zamykaniu kanału po operacji zapisu danych w buforze pozostają pewne dane, które oczywiście trzeba zachować. Można to zrobić na dwa sposoby: po pierwsze - wyzerować sektor i nagrać na nim owe dane, po drugie zaś, można je "nałożyć" na poprzednią zawartość tego sektora. Podanie rozszerzenia /T wymusza właśnie ten drugi sposób zapisu. Każde inne (lub jego brak) wybiera pierwsza z podanych opcji. Tyle informacji na temat obsługi handlera. Sposób jego wykorzystania zależy już od inwencji i wyobraźni użytkownika. Ze swej strony chciałbym zaprezentować dwa najbardziej typowe przykłady. Listing nr 2 przedstawia program kopiujący wspomagający handler. Niestety, standardowe kopiery nie radzą sobie dobrze z odczytem z urządzenia - po prostu czytają dane o długości równej objętości swego bufora, co z reguły nie jest nikomu potrzebne. Mój program likwiduje tę niedogodność, pytając użytkownika o liczbę bajtów do odczytu. Kopier pracuje w trybie konwersacji, za każdym razem podając rozmiar dostępnej pamięci RAM (ok. 29 Kb) i długość pliku w buforze. Wpisanie "*" powoduje wyświetlenie katalogu dyskietki, kropka (".") kasuje bufor i przestawia program w tryb odczytu danych, zaś "Q" powoduje zakończenie pracy i przekazanie sterowania do BASIC-a. Trzeci listing zainteresuje z pewnością użytkowników Quick Assemblera. Tworzy on malutki programik, który będzie odczytywany jako boot dyskowy. Wystarczy jedynie przed wczytaniem QA uruchomić handler, po czym (już w QA) wybrać opcję OBJ, jako nazwę pliku docelowego podać "A:1" i uruchomić opcję asemblacji. Proszę zwrócić uwagę na instrukcję OPT %1100101 powodującą przesłanie kodu wynikowego na urządzenie zewnętrzne bez nagłówków. Po dokładniejsze wyjaśnienia samego programu odsyłani do artykułu Lesława Pasternaka pt. "BOOT" ("TA" 6/91). org $0700 opt %1100101 *---- Naglowek boot dta b(0),b(1) dta a($700) dta a(start) *---- Inicjalizacja clc rts *---- Pisz tekst start ldxI na zakończenie kilka informacji technicznych. Po przepuszczeniu listingu nr 1 przez "Zgrywusa" otrzymujemy program zawarty w pliku binarnym. Pozwala to na używanie go jako komendy zewnętrznej CP.SYS-a. Handler sam się relokuje i podnosi nad siebie MEMLO (użyłem do tego celu metody przedstawionej w TA 8/91), zajmuje zaś około 850 bajtów RAM. Można tę przestrzeń bardzo łatwo zwolnić, naciskając RESET+START. Program został napisany przy pomocy Quick Assemblera. 1000 REM *--------------------------* 1002 REM : Handler "A:" : 1004 REM : autor: Maciej Czarnota : 1006 REM : (c) 1992 Tajemnice ATARI : 1008 REM *--------------------------* 1010 DATA ffff0090e392a240a0902042c6 1020 DATA a200bd1a03c900f01ac941f00d 1030 DATA e8e8e8e021d0eea278a090d004 1040 DATA a25fa09068684c42c6a201b50c 1050 DATA 9d9890bde702950cca10f3a292 1060 DATA a0904c42c6413a2068616e646c 1070 DATA 657220762e204949206279204d 1080 DATA 2e437a61726e6f74619b48616e 1090 DATA 646c6572206a65737420616b74 1100 DATA 79776e79202121fd9b4272616b 1110 DATA 206d69656a7363612077204841 1120 DATA 54414253202121fd9b4f2e6b2e 1130 DATA 9b209790ad1fd0c906d030ad7e 1140 DATA 92c50cd020ad7f92c50dd019a2 1150 DATA 01bd9890950cbd7e929de702ca 1160 DATA 10f2ae8092ac81924c42c6ae82 1170 DATA 92ac83922042c6a241ac8492ad 1180 DATA 85922086e4a9008da892ad8692 1190 DATA 8de702ad87928de80260ada892 1200 DATA f003a0a160a52a8da592a0008c 1210 DATA a492c8c88ca89284f2a52485f3 1220 DATA a52585f42000d89003a0ff6020 1230 DATA d2d9a5d48da292a5d58da392a9 1240 DATA 008da99220dd91b014c92fd010 1250 DATA e6f220dd91b009c954d005a980 1260 DATA 8da992201292adea0229e0a002 1270 DATA d99992f0068810f8a0fe608ca7 1280 DATA 9220f791a00160a0008ca892ad 1290 DATA a592c904f030aca492f02b88b9 1300 DATA e492998004c000d0f59899e492 1310 DATA c8d0faada992f003202092aca4 1320 DATA 9288b9800499e492c000d0f520 1330 DATA 2492a00160aca492d00b202092 1340 DATA 20f79120ee91a000b9e492c8cc 1350 DATA a692d002a0008ca492a00160ac 1360 DATA a49299e492c8cca692d00b2024 1370 DATA 9220ee9120f791a0008ca492a0 1380 DATA 016020a1dba4f2b124c99bf005 1390 DATA c900f0011860eea292d003eea3 1400 DATA 9260aca792b996928da692ada3 1410 DATA 92d00cada292c904b005a9808d 1420 DATA a69260a9048dd502a9008dd602 1430 DATA a953d006a952d002a9508d0203 1440 DATA ada7920aa8b99c928dd502b99d 1450 DATA 928dd602ada2928d0a03ada392 1460 DATA 8d0b03a9018d0103ad7c928d04 1470 DATA 03ad7d928d0503ada392d011ad 1480 DATA a292c904b00aa9808dd502a900 1490 DATA 8dd6022053e41008c08bd002a0 1500 DATA 8868686000e4929790aa92c392 1510 DATA 8892e493ed905f919e91bf915c 1520 DATA 915c9100008080000080208000 1530 DATA 80000001000000000000000041 1540 DATA 3a2068616e646c6572206f6469 1550 DATA 6e7374616c6f77616e799bfd4e 1560 DATA 6965206d6f6765206f64696e73 1570 DATA 74616c6f7761632068616e646c 1580 DATA 657261219be493ae9400200090 1590 DATA a9608de593a90085cfade70285 1600 DATA d4ade80285d538a99785d2e5d4 1610 DATA 85d0a99085d3e5d585d1a000f0 1620 DATA 033866cfa5d2c9e5a5d3e99390 1630 DATA 14ade7021869038daf94ade802 1640 DATA 69008db0946caf9424cf706330 1650 DATA 27b1d285ce91d420a294aaf0cd 1660 DATA c920f017c940f0c8c960f0c429 1670 DATA 0dc908f0be90418a291fc909f0 1680 DATA 3ab1d2c8c997b1d288e9909012 1690 DATA b1d2c8c9e5b1d288e993b006a5 1700 DATA d0a6d1900724cf3090a900aa85 1710 DATA d686d738b1d2e5d691d420a294 1720 DATA b1d2e5d74c9a94b1d291d420a2 1730 DATA 944c1394e6d2d002e6d3e6d4d0 1740 DATA 02e6d560e002e102e593 2 REM Kopier wspomagajacy handler A: 3 REM Autor : Maciej Czarnota ' 02.92 5 GRAPHICS 0:POKE 710,0:? " ACopier ve r. 1.0":DIM P$(29),F$(17),PR$(20),OP(2 ) 10 REM Ustalenie zmiennych 15 PR$="odczytu zapisu ":OP(1)=7: OP(2)=11:OD=1:LM=PEEK(144)+256*PEEK(14 5):HM=PEEK(560)+256*PEEK(561) 20 MX=HM-LM:RESTORE :FOR I=1 TO 29:REA D A:P$(I,I)=CHR$(A):NEXT I 25 REM Przygotowanie odczytu 30 ILE=MX:BUF=0 35 REM Wlasciwa procedura kopiera 40 ? :? "Bufor : ";MX:? "W buforze : " ;BUF:? :? "Podaj nazwe pliku do ";PR$( OD*10-9,OD*10) 45 INPUT F$:IF F$="" THEN 40 50 IF F$="*" THEN GOSUB 115:GOTO 40 55 IF F$="Q" THEN GRAPHICS 0:CLR :END 60 IF F$="." THEN OD=1:? CHR$(125);:GO TO 30 65 IF F$(1,1)="A" AND OD=1 THEN GOSUB 100 70 REM Tu zapis/odczyt programu 75 TRAP 90:OPEN #1,4*OD,128,F$:A=USR(A DR(P$),OP(OD),ILE):CLOSE #1 76 IF OD=1 THEN OD=2:ILE=PEEK(856)+256 *PEEK(857):BUF=ILE 80 GOTO 40 85 REM Obsluga bledow 90 CLOSE #1:? CHR$(253);"ERROR - ";PEE K(195):GOTO 40 95 REM Podprogram obslugi odczytu z A 100 ? "Ile bajtow ":TRAP 75:INPUT ILE: IF ILE>MX THEN ? "To przekracza objeto sc bufora":GOTO 75 105 RETURN 110 REM Directory 115 TRAP 90:OPEN #1,6,0,"D:*.*" 120 TRAP 125:INPUT #1,F$:? F$:GOTO 120 125 CLOSE #1:RETURN 130 REM Procedurka JMP $E456 135 DATA 104,104,104,162,16,157,66,3,1 65,144,157,68,3,165,145,157,69,3,104,1 57,73,3,104,157,72,3,76,86,228 Maciej Czarnota
|