Ready64 Forum
Commodore 64 => Programmazione, Grafica e Musica => Topic aperto da: Cbm - 26 Giugno 2006, 00:59:21
-
:c64: iao a tutti.
Ho pensato di stendere nei prossimi giorni, un programmino che permetta di velocizzare le azioni di manutenzione più comuni che si possono fare tramite il Commodore DOS, tale da permettere a chiunque di operare sui dischi senza conoscerlo, o di rendere le operazioni più rapide a favore dei più pigri. Operazioni che sicuramente saranno più familiari e necessarie a chi usa macchine vere e non l'emulatore, e che comunque sono offerte da tanti programmi per pc, anche l'idea è far si che il biscottone se la sbrighi da solo senza supporto esterno.
Il programma avrà un'interfaccia a menù testuali, campo dove il Basic offre il meglio di sè stesso, occasione buona per me per usarlo, sperando umilmente che il contenuto del listato, sia un pò di aiuto didattico, circa i comandi disco, a quei pochi "novizi" che ne sanno meno di me.
Saluti
-
L'ho chiamato "Il Discobolo" :D
Intanto ecco la schermata di avvio.
(http://i46.photobucket.com/albums/f105/ccccccte/Intro.jpg)
Ne ho praticamente finito il listato e sembra funzionare tutto per bene.
Il programma per adesso gestisce solo le funzioni più comuni del DOS, anche se penso più avanti di implementare qualche comando meno usato e di perfezionarlo.
Ho fatto in modo che il programma, all'avvio interroghi d'ufficio il canale disco, in modo da evitare che, chiedendo lo status del dischetto durante l'esecuzione, il lettore la prima volta comunichi, invece dello stato del disco stesso, la conferma dell'accensione del lettore, obbligando quindi a ripetere la richiesta e confondendo le idee ai meno pratici. Non credo ci sia un modo per evitare tale comportamento senza usare artifizi. Che ne dite?
Alla prossima.
-
BELLO! e quando ce lo passerai? 8)
-
BELLO! e quando ce lo passerai? 8)
E' che non avevo un posto dove metterlo e volevo rileggere bene il codice; al limite lo faccio dopo.
Eccolo qui: ------------ (collegamento eliminato in favore di quello interno al sito riportato nel proseguio della discussione)
Ogni critica o suggerimento è ben voluta.
Oltre alle funzioni tipo formatta, rinomina, cancella ecc... il programma può fare un test sullo stato del disco. Utile anche se un operazione su disco va male (non necessariamente eseguita dal programma, ma anche con comandi diretti). Se lanciato il test subito dopo l'operazione fallita, da l'errore (testo e codice) che lo ha causato (purtroppo è testato solo con l'emulatore).
Tutte cose che comunque si possono fare direttamente a colpi di open; per cui chi non sa come si usano i comandi diretti e volesse andare oltre l'uso comodo e vedere un pò di capirli da sè, potrà risalirci facilmente dal listato.
:ciauz:
-
Gran programma!
servirebbe un bel lettore hex delle tracce.. e sarebbe un clone del PCTools dei primi anni 90!
torna veramente utile in molte situzioni.
non è opensource? :metal: :D
-
Ho fatto qualche piccola modifica al file pubblicato.
Ora è possibile usare anche il comando INITIALIZE, e per quanto riguarda la formattazione si può scegliere pure quella rapida.
-
Voglio essere sincero e franco, per non dare illusioni.
Trovo il programma abbastanza inutile nella forma attuale, esistono decine
di shell/wedges/disk tools molto piu' versatili e potenti sin dagli albori,
basta vedere sul disco stesso fornito con il 1541, ma al di la' della
valutazione soggettiva, e considerandolo pura didattica, presenta evidenti
vizi di forma. Vediamo che si puo' migliorare:
5 FOR a=1 TO 11:READ l$:FOR r=1 TO 200:NEXT r
85 FOR t1=1 TO 1000:NEXT t1
95 FOR t2=1 TO 2500:NEXT t2
e cosi' via per tutto il resto del programma: fai uso eccessivo di
variabili temporanee. Usa meno variabili possibile, occupano memoria e
piu' ne usi piu' il basic ci impiega a cercarle quando vuoi usarle.
510 ON n GOTO
ON GOSUB e' meglio in questi casi.
1000 OPEN 1,8,15
1010 INPUT#1,e$,er$,t$,s$
1020 CLOSE 1
1050 PRINT "stato del disco inserito":PRINT
Ma quale "stato del disco INSERITO"?? =)
E' solo lo stato del drive.
1060 PRINT:IF er$="ok" THEN PRINT "nessun errore presente"
Non e' certo cosi' semplicemente che si controllano gli errori nei
settori del floppy.
2020 PRINT:PRINT "{!*3} il file ''";ca$;"''"
Inezia formale: non usare 2 apici, per stampare il doppio apice usa CHR$(34)
2040 PRINT:INPUT "sei certo di voler procedere (s/n)";co$
2050 IF co$="s" THEN GOTO 2065
2055 IF co$="n" THEN GOTO 10010
2060 GOTO 2040
Anche qua, usare subroutines
2070 OPEN 2,8,15,"s:"+ca$:CLOSE 2
Non e' un errore, ma mi chiedo perche'usare un numero di file sempre diverso
per ogni comando, e per di piu' una sub routine per ogni open/close...
Basterebbe una variabile stringa contenente il comando da eseguire, una sub
OPEN 1,8,15,co$:CLOSE 1
(eventuale controllo e stampa del codice di errore/ok che invece non fai mai)
e un RETURN
5070 OPEN 5,8,15,"n:"+fo$+fd$:CLOSE 5
Manca la virgola!
8000 PRINT "inizializzazione lettore"
8010 PRINT:INPUT "vuoi procedere con l'operazione (s/n)";in$
Operazione in cui e' inutile chiedere conferma.
Ora che ho fatto un po' di pulci, direi che puoi iniziare a sistemarlo,
giusto per fare un po' di pratica con le subroutines.
Ma la cosa piu' importante e' quella di aggiungere funzioni piu' utili
tipo la lettura della directory, lettura, editing e scrittura/spostamento di
blocchi sul disco, verifica e visualizzazione della BAM, test di
lettura/scrittura del disco per verifica errori.
Altrimenti, ripeto, un programma che fa SOLO i comandi base del dos non
serve davvero a niente.
-
Voglio essere sincero e franco
Tranquillo, è una cosa che apprezzo e prediligo. Grazie invece.
Io continuo a fare pratica nei ritagli di tempo e la scelta del programma è un pretesto per padroneggiare il dos con più naturalezza da un lato e concentrarmi su un obiettivo preciso dall'altro. Per l'uso sceglierei il dos wedge.
5 FOR a=1 TO 11:READ l$:FOR r=1 TO 200:NEXT r
85 FOR t1=1 TO 1000:NEXT t1
95 FOR t2=1 TO 2500:NEXT t2
e cosi' via per tutto il resto del programma: fai uso eccessivo di
variabili temporanee. Usa meno variabili possibile, occupano memoria e
piu' ne usi piu' il basic ci impiega a cercarle quando vuoi usarle.
Si, ne sono consapevole, l'ottimizzazione è un aspetto che mi affascina. Qui non mi sono preoccupato affatto di ottimizzare il listato e le prestazioni, alcune cose che rilevi sono proprio volute. In generale avevo pensato ad un listato il più banale possibile per essere più chiaro a chi sta peggio di me, magari invece ottengo l'effetto contrario man mano che vado avanti perchè diventerà lunghissimo. Anzi dovrei aggiungere i remark...
La prossima cosa che avevo pensato di fare è lo spostamento dei blocchi e il test automatico alla fine di ogni operazione.
Intanto faccio tesoro con interesse della tua disamina. Saluti.
-
Allora, complice il clima più favorevole ho iniziato ad eliminare qualche incongruenza tra quelle segnalatemi da iAN (grazie ancora), in particolare col recupero di ...una virgola sparita, grazie al quale ora la formattazione completa lo è davvero, cosa evidente anche in termini di tempo necessario per eseguirla :lol:
Ho modificato anche la conferma finale delle azioni eseguite, in modo che il canale venga interrogato in maniera silente alla fine di queste, e solo nel caso venga rilevato qualche problema vengano mostrati i risultati del test.
Ho comunque lasciato disponibile l'interrogazione su richiesta, non si mai.
-
Esco un attimo dal seminato:ce la faresti a scrivere qualcosa che indichi con quale densità sono registrati i vari settori del disco? :)
-
Per Alberto: credo di non seguirti; cosa intendi per "con quale densità"? Se la densità è il rapporto tra bit e centimetri quadrati (ora non ricordo più quanti bit per i dischi a bassa densità), è uguale per ogni dischetto della stessa categoria e tale rimane. Non ne capisco la misurazione. Forse sto parlando di altro?
-
Forse saprai che i vari settori dei dischi sono registrati con densità variabile, dipendente dalle dimensioni di ciascuna traccia (più densamente le tracce più interne,meno densamente quelle più esterne).
Talvolta però,i vari settori di una stessa traccia venivano registrati con densità diverse in modo che non fosse possibile duplicare i dati sul disco usando i normali comandi del DOS ad alto livello;il formato .g64 è stato introdotto proprio per tenere conto di queste variazioni.
Comunque era solo una curiosità.Si tratta di una feature piuttosto avanzata e di dubbia utilità:poteva servire (ai tempi) su un vero C64 per duplicare i dischi protetti,ma su un emulatore quali vantaggi se ne potrebbero trarre? :dotto:
-
Forse saprai che i vari settori dei dischi sono registrati con densità variabile, dipendente dalle dimensioni di ciascuna traccia (più densamente le tracce più interne,meno densamente quelle più esterne).
Ok.
Talvolta però,i vari settori di una stessa traccia venivano registrati con densità diverse in modo che non fosse possibile duplicare i dati sul disco usando i normali comandi del DOS ad alto livello;il formato .g64 è stato introdotto proprio per tenere conto di queste variazioni.
Ah ecco. Questo non lo sapevo proprio.
Comunque era solo una curiosità.Si tratta di una feature piuttosto avanzata e di dubbia utilità:poteva servire (ai tempi) su un vero C64 per duplicare i dischi protetti,ma su un emulatore quali vantaggi se ne potrebbero trarre?
Ora che ho capito il punto, posso risponderti senza dubbio che viste le mie conoscenze tutt'altro che avanzate (come la feature), ed anche che evidentemente conosco la "fisica" del disco solo di striscio, credo di non potermi cimentare ora come ora nel fare qualcosa di serio in tal senso. :doh:
-
L'altro ieri ho iniziato a studiare la struttura della traccia 18, scopo lettura della directory. Il manuale è di molto aiuto, ma non volendo limitarmi a copiare gli esempi, ma di comprendere il perchè di ciò che viene usato per lo scopo, sto riscrivendo da zero. Finora sta andando bene, sono riuscito a ottenere qualcosa di funzionante che mi permetta di vedere l'elenco dei files contenuti e l'intestazione del disco con l'id; le cose che in fondo sono quelle strettamente più utili a gestire i comandi presenti finora nel menù (tipi di file e blocchi occupati li ho tralasciati). Questo è l'abbozzo attuale.
5 OPEN 15,8,15
10 OPEN 1,8,0,"$"
20 PRINT " ";
30 FOR X=1 TO 28:GET#1,D$:IF X=27 OR X=28 THEN PRINT D$;
35 NEXT X:CLOSE 1:PRINT " [SU]"
40 OPEN 1,8,0,"$"
45 GET#1,D$:IF ST<>0 THEN GOTO 100
46 IF D$<>CHR$(34) THEN GOTO 45
50 GET#1,D$:IF D$<>CHR$(34)THEN PRINT D$;:GOTO 50
70 PRINT:IF ST=0 THEN GOTO 45
100 CLOSE 1:CLOSE 15
READY.
Il problema è che il programma funziona bene in certe occasioni, in altre invece si pianta tutto durante la lettura costringendomi al reset. Secondo voi potrebbe essere (anche) colpa dell'emulatore? Infatti se lancio il programma col turbo per provare, i blocchi sono molto più frequenti.
Sto cercando di ovviare, ma finora non trovo una soluzione.
-
Fai attenzione ad una cosa. Non si hanno gli stessi risultati aprendo "$" sul canale 0 o su un canale "normale".
Se apri "$" sul canale 0, ad esempio
OPEN 1,8,0,"$"
il drive ti invia la directory sotto forma di "programma BASIC", come quando fai LOAD"$",8.
Se invece apri "$" su un canale da 2 a 14, con
OPEN 2,8,2,"$"
o simili, solo allora il formato del "file" che ricevi e che rappresenta la directory, viene rispettato così come spiegato sul manuale e letto nel programma "lettura directory".
Le applicazioni più "avanzate" di lettura directory sono di fatto precluse se utilizzi l'artifizio del canale 0, pertanto, personalmente, ti consiglio di abituarti a lavorare su un canale normale (non 0 o 1) e di analizzare il funzionamento del programmino del manuale (è decisamente più utile che, impuntandosi nel "non voler copiare", provare a scrivere da zero, ma senza tenere conto da principio del formato della directory: è un po' come fare reverse engineering per ricavare delle specifiche che hai già a portata di mano). Cerca di individuare quali sono le GET# che "estraggono" le informazioni che ti servono.
Roberto Morassi su CCC n. 42 (pag. 60 e ss.) ha seguito un approccio ancora più radicale: studiandosi il formato della directory così come memorizzata sul disco (non cioè come "file" aperto con il nome "$", ma proprio nella struttura di ogni singolo settore della traccia 18, che si trova sempre sul manuale), ha realizzato una routine di lettura della directory basata sull'accesso casuale al disco, un po' come se stesse operando su un "suo" file casuale. Se te la senti, prova anche a capire il funzionamento della sua routine; devi però avere già dimestichezza con i file casuali (le spiegazioni sul loro utilizzo si trovano, ancora, sul manuale del drive).
-
IMHO la spiegazione dei file rels è un pò criptica sul manuale del drive,consiglio di leggere articoli specifici su CCC o il capitolo di "The anatomy of 1541" che ne parla.
-
Va benissimo, ma non mischiare le carte: si parla di file random, non di file relativi. ;)
-
Ops,come non detto ho letto male io :D
-
(è decisamente più utile che, impuntandosi nel "non voler copiare", provare a scrivere da zero, ma senza tenere conto da principio del formato della directory: è un po' come fare reverse engineering per ricavare delle specifiche che hai già a portata di mano).
Credo di aver usato il termine "da zero" in modo equivoco, infatti intendevo che sto scrivendo ex novo senza ricopiare, ma basandomi comunque su qualcosa di già visto, nella fattispecie la mia attenzione era stata catturata non dal programma di lettura directory, bensì da quello denominato DIR, situato nell'appendice C del manuale, che appunto fa la lettura usando il canale 0 del load, e non come file sequenziale. Forse perchè mi è venuto più chiaro interpetarne i passaggi.
Il guaio è che adesso ho creato il prg di DIR con bastext per vederlo girare, e che anche lui si blocca, in genere se la directory è lunga. :huh:
Se da un lato ciò vuol dire che il problema non è in ciò che ho scritto io, dall'altro lato questo risultato non mi aiuta a capirne il motivo, cosa che invece vorrei decisamente conoscere.
-
Haha, mi ero dimenticato del programmino in appendice. :lol: Ribadisco comunque il concetto espresso, che per avere le informazioni "avanzate" è necessario almeno il ricorso ad un canale tra il 2 e il 14.
Be', comunque, se ti fa "crash" con qualche immagine D64 reperibile in rete, indicamela, così faccio una prova. E visto che sospetti dell'emulatore, che emulatore e che versione stai usando?
-
Be', comunque, se ti fa "crash" con qualche immagine D64 reperibile in rete, indicamela, così faccio una prova. E visto che sospetti dell'emulatore, che emulatore e che versione stai usando?
Ops... stavo consolandomi lavorando al catalogo di CCC. Il problema me lo dà con diverse immagini, anche se le creo e le riempio di files all'uopo. CCS 2.0. Sto notando che più files ci sono più è matematico il congelamento...
-
Ho steso in fretta e furia un piccolo listato Basic per la lettura e l'output delle entry su disco che vuole essere un esempio (non certo il migliore) di come si possano leggere le entry del disco.@Cbm:osserva le subroutine alle linee 100,115,125 e integrando col manuale del drive,cerca di capire come funzionano.
start tok64 direct.prg
0 rem semplice lettura e output della dir
5 tr=18
6 sc=0
7 err=0
10 open 1,8,15
15 open 2,8,2,"#"
20 gosub 100
25 ps=144:gosub 115
30 for i=0 to 19:get#2,a$:print a$;:next:print:print
35 if asc(t$+chr$(0))=0 then 90
40 tr=asc(t$+chr$(0)):sc=asc(s$+chr$(0))
45 gosub 100
50 ps=3
55 gosub 125
60 if err=1 then 90
65 goto 35
90 close 2:close 1:end
99 rem -*** caricamento del settore ***-
100 print#1,"u1:"2;0;tr;sc
105 get#2,t$:get#2,s$
110 return
114 rem -* posizionamento nel settore *-
115 print#1,"b-p:"2;ps
120 return
124 rem -****** lettura della dir *****-
125 for i=1 to 8
130 gosub 115:get#2,a$:if asc(a$+chr$(0))=0 then err=1
135 if err=1 then 155
140 ps=ps+2:gosub 115
145 for j=0 to 15:get#2,a$:print a$;:next:print
150 ps=ps+30:next
155 return
stop tok64
Ciauuuuuuu
p.s.:forse il puntatore al primo blocco dati come terminatore non è la scelta migliore,ma sono certo che tu scriverai qualcosa di meglio per la tua utility ;)
-
Senza troppe complicazioni, questo e' sufficiente
start tok64 dd.prg
10 close1:open1,8,0,"$0:*,p,r"
19 rem salta i primi 4 bytes (loadaddres e link)
20 x=4
30 fori=1tox:get#1,c$:ifst<>0then100
35 next
39 rem stampa dimensione, byte basso+byte alto*256
40 gosub200:d=asc(c$):gosub200:d=d+(asc(c$)*256):print"{left}"d;
41 rem stampa nome finche' non trovi 0
45 gosub200:printc$;:ifc$<>chr$(0)then45
46 print
49 rem salta 2 byte (link prossima riga)
50 x=2:goto30
100 close1:end
200 get#1,c$:ifc$=""thenc$=chr$(0)
201 return
stop tok64
Cosi' facendo si legge e interpreta il programma basic inviato dal drive quando si richiede il file "$"
Notare la linea 200, e' necessario patchare la variabile per ovviare al baco di interpretazione del chr$(0), che e' il terminatore stringa: la get# non assegna cs=chr$(0) ma solo stringa vuota, e dobbiamo rimettercelo dentro noi per far si che poi le operazioni su stringa non diano errore.
Questo programma l'ho convertito da asm, dalla routine che postai qua
http://ready64.org/smf/index.php?topic=658.0 (http://ready64.org/smf/index.php?topic=658.0)
Scartabellando tra vari dox ho trovato un simpatico metodo
start tok64 2line.prg
1 D=peek(186)
1000 SYS57812"$",D:POKE43,1:POKE44,192:POKE768,174:POKE769,167:SYS47003,1
1010 POKE782,192:SYS65493:SYS42291:LIST:POKE44,8:POKE768,139:POKE769,227
stop tok64
la locazione 186 contiene l'ultimo drive usato.
La prima sys setta il nome del file da aprire e da quale drive farlo.
I puntatori della memoria basic sono rediretti a $c001, il vettore $0300 dei messaggi del basic rediretti a $a874 (per non visualizzare alcun messaggio del tutto, nascondendo i vari "searching" "loading" etc), effettua il load, un relink del programma caricato a $c001 e lo lista, dopodiche' ritorna all'area normale ripristinando il vettore $0300.
Affascinante.
-
In ritardo, ma ecco anche il mio risultato. Ero già preso e non ho colpevolmente tenuto conto dei contributi vostri, ma li studierò lo stesso domani (bello quello coi poke, minuscolo e... diverso).
Pur con delle differenze e con delle dimensioni ridotte, è troppo legato come sequenza dei passaggi al programma DIR preso come modello, lo so.
start tok64 roulist.prg
1000 PRINT"{clear}{C*28}"
1010 OPEN 1,8,0,"$":g=1
1020 FOR g=g TO 3:GET#1,d$,d2$:NEXT g
1030 b=0:g=2
1040 IF d$<>"" THEN b=ASC(d$)
1045 IF d2$<>"" THEN b=b+ASC(d2$)*256
1050 PRINT "(" MID$(STR$(b),2);")";TAB(5);
1060 GET#1,d$:IF st<>0 THEN 1090
1065 IF d$<>CHR$(34) THEN 1060
1070 GET#1,d$:IF d$<>CHR$(34)THEN PRINT d$;:GOTO 1070
1075 GET#1,d$:PRINT d$;:IF d$<>"" THEN 1075
1080 PRINT:IF st=0 THEN 1020
1090 PRINT"{left} blocchi liberi)":CLOSE 1
1095 PRINT"{C*28}"
stop tok64
Il listato ha anche un pò di formattazione del testo perchè l'ho già integrato nel resto del programma dimostrativo, nel quale, prima di caricarlo sullo spazio, ho corretto anche un errore nel codice che era nato dalla "rinumerazione" delle righe fatta la volta precedente e che mi era sfuggito.
Credo sia utile riportare, come esperienza fatta, che per comprendere meglio il contenuto del settore e come questo sia strutturato all'interno del settore stesso, in modo da sapere come poterlo utilizzare, ho trovato molto utile in fase di studio, farmi rappresentare il tutto sotto forma di codice ASCII, chiedendo di volta in volta la stampa del contenuto estratto da GET# con PRINT ASC(X$)
Infine per completezza, una cosa che avevo dimenticato di riferire nel frattempo, e cioè che quel problema di blocco del sistema di cui parlavo nei messaggi dell'8 agosto, era un problema mio, dovuto all'emulatore come sospettavo. Quindi come non detto.
:c64: iao.
-
A proposito della lettura directory, ho fatto una piccola modifica al .prg messo in rete, prevedendo la possibilità, su richiesta, di inviare il risultato della lettura alla stampante per averlo su carta. Naturalmente la stampa è testata solo su emulatore, ovvero stampa su file .txt.
-
Bene bene :mattsid: , vista la nuova possibilità offerta, carico anche io il file direttamente qui, così evito di usare uno spazio esterno e ho tutto sottomano.
Grazie Roberto!
-
Finalmente ho avuto la voglia e il tempo di fare qualche giorno di immersione totale, toccando i comandi USER in lettura-scrittura e l'uso del buffer, quindi studiando e riproponendo il codice necessario ad ottenere una vista grafica della BAM, in stile "forza 4", le cui istruzioni trovate aggiunte a partire dalla riga 1500. Alla 1550 è presente la funzione chiave: DEF FNS(Z)=2^(S-INT(S/8)*8) AND (SB(INT(S/8)))
Utilizzando gli stessi comandi e in aggiunta al resto, con istruzioni questa volta a partire dalla riga 7000, ho introdotto nel programma l'utile possibilità, non permessa con comandi diretti come avviene per i file, di dare un nuovo nome al disco senza per questo ricorrere alla sua formattazione. Ciò diventa possibile sostituendo la denominazione precedente, scrivendo direttamente sul blocco 0 della famosa traccia 18, a partire dal byte 144, zona dove si trova memorizzata l'informazione relativa al nome del disco.
-
Finalmente ho avuto la voglia e il tempo di fare qualche giorno di immersione totale, toccando i comandi USER in lettura-scrittura e l'uso del buffer, quindi studiando e riproponendo il codice necessario ad ottenere una vista grafica della BAM, in stile "forza 4", le cui istruzioni trovate aggiunte a partire dalla riga 1500. Alla 1550 è presente la funzione chiave: DEF FNS(Z)=2^(S-INT(S/8)*8) AND (SB(INT(S/8)))
Utilizzando gli stessi comandi e in aggiunta al resto, con istruzioni questa volta a partire dalla riga 7000, ho introdotto nel programma l'utile possibilità, non permessa con comandi diretti come avviene per i file, di dare un nuovo nome al disco senza per questo ricorrere alla sua formattazione. Ciò diventa possibile sostituendo la denominazione precedente, scrivendo direttamente sul blocco 0 della famosa traccia 18, a partire dal byte 144, zona dove si trova memorizzata l'informazione relativa al nome del disco.
CHE M***A (attenzione alle paroline... ndHiryu) HAI DETTOOOOOOOOOOOO ??????? Esprimiti in aramaico, lo capisco meglio!!!!!! :lol: :ciapet: :fagiano: