Ok ho capito,lo faccio io.
Si può inserire nella routine di interrupt un controllo del tipo
lda $91
bpl rest ;RUN-STOP?
cmp #239
beq stop ;SPC?
Come si nota,si salta a stop ogni volta che viene premuto il tasto spazio.
La routine di arresto/riavvio è la seguente (per maggiori informazioni su come si gestisce$dc0d,consultare MTC64).
;ferma/riprende il conteggio
stop
lda #2
sta $dc0d
lda stop+1
eor #$80
sta stop+1
done
jmp ret
Alcune note sul listato completo:l'ultima linea della routine di reset permette di resettare il cronometro anche quando è fermo,mentre lo switch sulla condizione di tasto premuto serve a evitare che,data la frequenza dell'interrupt,il cronometro venga arrestato e/o riavviato più volte ad ogni pressione della spacebar.
Siamo comunque ancora ben lontani dalla perfezione,per cominciare:
1. La tecnica usata per arrestare il cronometro è semplice,ma anche molto approssimativa.
In effetti inibire le IRQ del timer B non significa fermarlo,per cui avremo un errore di anticipo o di ritardo alla ripresa del conteggio.Con una risoluzione di un centesimo di secondo l'errore non è percettibile da un essere umano,ma può diventarlo per risoluzioni maggiori,ad esempio di un secondo.
In quel caso sarebbe molto più saggio arrestare il timer B per poi riavviarlo,come suggerito da iAN CooG.
2. La precisione del cronometro è comunque scarsa,perchè la routine gestisce DUE sorgenti di IRQ,per cui è possibile che di tanto in tanto i due timer si "pestino i piedi":niente di male se il timer A resta in attesa di vedere servita la IRQ del timer B,ma la situazione opposta implica un rallentamento nel conteggio.
3. Scegliere il tasto spazio come interruttore non è il massimo;sarebbe meglio un tasto funzione tipo CTRL altrimenti si può stampare a schermo qualcosa di indesiderato.
Chi vuole provare a migliorare la routine tenga presente che usando CTRL lo switch su $c5 non funzionerà,perchè questa locazione viene modificata solo per evitare letture ripetute di uno stesso carattere.
4. Non è previsto il caso in cui si voglia tornare alle condizioni standard (ancora da implementare,volontari? B) ).
Spero che queste osservazioni possano essere utili a qualcuno.Posto il codice
screen = $400
norm = $ea31
ret = $ea81
ref = $fb
.word eop
.word 7102
.byte $9e
.asc "2061"
.byte 0
eop
.word 0
lda #$40
sta 650 ;disattiva repeat (per SPC)
lda #$f0
sta sw
jsr draw
sei
lda #<irq
sta $314
lda #>irq
sta $315 ;irq vect
lda #$7c
sta $dc06
lda #$26
sta $dc07 ;~ 0.01 sec
lda #$82
sta $dc0d ;irq timer B on
lda #1
sta $dc0f ;timer B on
cli
rts
irq
lda $c5
cmp #$40 ;tasto premuto?
sw
beq cont
lda sw
eor #$20
sta sw
lda $91
bpl rest ;RUN-STOP?
cmp #239
beq stop ;SPC?
cont
lda $dc0d
lsr
bcc skip
jmp norm ;irq normale
skip
ldx #7
ldy #"9"
jsr rfrsh ;centesimi
cmp #"0"
bne exit
dex
jsr rfrsh ;decimi
cmp #"0"
bne exit
dex
dex
jsr rfrsh ;secondi
cmp #"0"
bne exit
dex
ldy #"5" ;0-59 sec
jsr rfrsh ;10 sec
cmp #$30
bne exit
dex
dex
ldy #"9"
jsr rfrsh ;minuti
cmp #$30
bne exit
dex
ldy #"5" ;0-59 min
jsr rfrsh
exit
jsr draw
jmp ret
;aggiorna il conteggio
rfrsh
sty ref
lda time,x
cmp ref
bne ok
lda #$2e ;-2 perchè il carry è settato
ok
adc #1
sta time,x
rts
;stampa il conteggio
draw
ldx #7
lp1
lda time,x
sta screen,x
dex
bpl lp1
rts
;resetta il conteggio
rest
ldx #7
lp2
lda time+8,x
sta time,x
dex
bpl lp2
jmp exit
;ferma/riprende il conteggio
stop
lda #2
sta $dc0d
lda stop+1
eor #$80
sta stop+1
done
jmp ret
time
.text "00:00:0000:00:00"