![]() |
MikrocomputertechnikProf. Jürgen Plate |
data equ $2000 ; data area (e-ram)
stak equ $7FFF ; stack area (e-ram)
prog equ $8000 ; programm area (e-eerom)
rvec equ $FFFE ; reset vector
pioc equ $1002 ; parallel i/o control
portb equ $1004 ; port b data
portcl equ $1005 ; port c data latch
portc equ $1003 ; port c data reg.
ddrc equ $1007 ; portc data dir. reg.
tmsk equ $1024 ; timer mask
tflg equ $1025 ; timer flag
pacr equ $1026 ; pulse accu control
baud equ $102B ; SCI-baudrate
sccr1 equ $102C ; SCI-control1
sccr2 equ $102D ; SCI-control2
scsr equ $102E ; SCI-status
scdr equ $102F ; SCI-data
***************************
* data area *
***************************
org data
***************************
* program area *
***************************
org prog
main lds #stak ; load stackpointer
* Parameter: A Länge (Anzahl Bytes), X Quelle, Y Ziel
move pshb
mov1 ldab 0,x ; hole Quellbyte
stab 0,y ; speichern im Zielbereich
inx ; Adressen erhöhen
iny
deca ; runterzählen bis 0
bne mov1
pulb
rts
LDAA $40 ; 1. Zahl holen
CMPA $41 ; 2. Zahl größer?
BHS WEITER ; 1. Zahl ist größer
LDAA $41 ; 2. Zahl laden
WEITER STAA $42 ; Abspeichern
CHECKSUM CLRA ; Summe in A und B, Register
CLRB ; zuerst mal löschen
LDX #$0043 ; Adresse erster Summand (Feldanfang)
CSUM ADDB ,X ; Feldelement addieren
ADCA #0 ; Übertrag im MSB aufaddieren
INX ; X inkrementieren
DEC $42 ; Elementezähler vermindern
BNE CSUM ; Wiederholen, solange Zähler > 0 ist
STD $40 ; Checksumme speichern
RTS
LDAB $41 ; Operanden holen
LDX #TABELLE ; X-Register auf Tabellenanfang
ABX ; X und B addieren
LDAA 0,X ; B-ten Eintrag aus Tabelle holen
STAA $42 ; und abspeichern
TABELLE DC.B 0,1,4,9,16,25,36,49,64,81,100
DC.B 121,144,169,196,225
org data
eins dc.b 04,82,40 ; 1. Summand
zwei dc.b 02,37,98 ; 2. Summand
drei dc.b $00,$00,$00 ; Ergebnis
org prog
.
.
.
ldaa eins+2
adda zwei+2
staa drei+2
ldaa eins+1
adca zwei+1
staa drei+1
ldaa eins+0
adca zwei+0
staa drei+0
.
.
.
LDAB #4 ; Zahlen sind 4 Byte lang = 8 Stellen
LDX #$41 ; 1. Operand
LDY #$51 ; 2. Operand
CLRA ; Akku A (und Carry-Flag) löschen
BCDADD LDAA 0,X ; zwei Ziffern des 1.Operanden holen
ADCA 0,Y ; zwei Ziffern des 2.Operanden addieren
INY
DAA ; Dezimalkorrektur für BCD
STAA 0,X ; Ergebnis abspeichern
INX
DECB
BNE BCDADD ; solange, bis alle Stellen bearbeitet
ANZAHL EQU 20 ; z.B. 20 Feldelemente
FELD DS.B 20 ; Platz für 20 Werte
COUNT DS.B 1 ; 1 Byte Zähler
.
.
.
CLRB ; Zähler für neg. Elemente löschen
LDX #FELD ; X auf Feldanfang
LDAA ANZAHL
STAA COUNT ; Zähler setzen
LOOP LDAA 0,X ; nächstes Feldelement
BPL WEITER ; wenn positiv weiter
INCB ; negative Elemente zählen
WEITER INX
DEC COUNT
BNE LOOP ; bis alle Elemente getestet sind
STAB COUNT ; Ergebnis in COUNT speichern
.
.
.
clr portb ; Portb auf 0 setzen
ldab #%1010 ; Register B setzen
ldaa #%11110000 ; Port C Richtungsregister setzen:
staa ddrc ; Bits 0-3 Eingabe, 4-7 Ausgabe
loop ldaa portc ; Port C lesen
anda #$0F ; untere 4 Bits ausmaskieren
staa portb ; auf Port B ausgeben
stab portc ; Register B ausgeben
eorb #%11110000 ; und Bits 4-7 invertieren
bsr delay ; 0,5 s warten (siehe unten)
jmp loop ; endlosschleife
.
.
.
prog equ $8000
data equ $2000
stack equ $7FFF
pioc equ $1002 ; parallel i/o control
portb equ $1004 ; port b data
portc equ $1005 ; port c data latch
portcl equ $1005 ; port c data latch
tmsk equ $1024 ; timer mask
tflg equ $1025 ; timer flag
pacr equ $1026 ; pulse accu control
baud equ $102B ; SCI-baudrate
sccr1 equ $102C ; SCI-control1
sccr2 equ $102D ; SCI-control2
scsr equ $102E ; SCI-status
scdr equ $102F ; SCI-data
reset equ $fffe
org data
key ds.b 1
org prog
main lds #stack ; load stackpointer
clr key
ldaa #%01010000 ; pa7 freigabe pos. flanke
staa pacr
clra
loop bsr taste
ldaa key
staa portb
bra loop
taste psha
ldaa tflg ; taste gedrueckt?
anda #$10
beq tend ; nix gewesen
ldaa #$10
staa tflg ; Anforderung loeschen
com key ; Ereignis melden
tend pula
rts
org reset
fdb main
end
; Vereinbarungen
prog equ $8000
data equ $2000
stack equ $7FFF
portb equ $1004
portc equ $1003
portcl equ $1005
pioc equ $1002
ddrc equ $1007
reset equ $fffe
.
.
org data ; Datenbereich
tflag ds.b 1
.
.
org prog ; Programmbereich
main lds #stack ; Stackpointer laden
clr portb ; Ports/Variablen init.
ldaa #1 ; tflag = 1
staa tflag
loop bsr count ; Hauptschleife, nur zwei UP-Aufrufe
bsr taste ; Taste abfrage
jmp loop ; auf/ab zaehlen
; Zaehl-Unterprogramm
; tflag wird addiert (tflag kann 1 oder -1 sein)
count adda tflag ; zaehlen
staa portb ; ausgeben
bsr delay ; 0,5 s warten (siehe unten)
rts
; Tasten-Abfrage-UP
; bei jedem Tastendruck wird tflag negiert (+1
-1, -1
+1)
taste psha ; Akku A retten
ldaa pioc ; Taste gedrueckt
bpl njet ; nein
fertig
ldaa portcl ; dummy-read zum Ruecksetzend es Tastenbits in pioc
neg tflag ; tflag negieren
njet pula ; Akku A restaurieren
rts
.
.
.
Alternativlösung mit bedingter Verzweigung
loop bsr delay
tst updn
bne decr
inc count
ldaa count
cmpa #$FF
bne endf
com updn
bra endf
decr dec count
ldaa count
tsta
bne endf
com updn
endf ldaa count
staa portb
jmp loop
Die Bedienung des Timer-Interrupts wird hier nur angedeutet (da noch nicht behandelt). Der CLOCK-Interrupt wird im Beispiel alle 100 ms ausgelöst = 10 Tics/s.
ZEHNTEL DS.B 1 ; 1/10 Sekunden
SEKUNDEN DS.B 1 ; Sekunden
MINUTEN DS.B 1 ; Minuten
STUNDEN DS.B 1 ; Stunden
.
.
.
CLOCK
* An dieser Stelle muß die
* Timer-Hardware bedient werden
INC ZEHNTEL ; 1/10 Sekunden erhöhen
LDAA #10
CMPA ZEHNTEL ; Sekunde erreicht?
BNE ENDCLOCK ; nein - fertig
CLR ZEHNTEL ; sonst 1/10 Sekunden auf 0 setzen
INC SEKUNDEN ; und Sekunden erhöhen
LDAA #60
CMPA SEKUNDEN ; Minute erreicht?
BNE ENDCLOCK ; nein - fertig
CLR SEKUNDEN ; sonst Sekunden auf 0 setzen
INC MINUTEN ; und Minuten erhöhen
CMPA MINUTEN ; Stunden erreicht?
BNE ENDCLOCK ; nein - fertig
CLR MINUTEN ; sonst Minuten auf 0 setzen
INC STUNDEN ; und Stunden erhöhen
LDAA #24
CMPA STUNDEN ; Tageswechsel?
BNE ENDCLOCK ; nein - fertig
CLR STUNDEN ; sonst Stunden auf 0 setzen
ENDCLOCK RTI ; Rücksprung
Die Dauer der ISR beträgt im schlechtesten Fall weniger als 150 Taktzyklen. Da die ISR nur alle 100 ms ausgelöst wird, ist die zusätzliche Belastung des Systems relativ gering (ca. 0,1%).

EVENPAR PSHB ; Codewort zwischenspeichern
CLRA ; Zaehler = 0
ZHL LSRB ; naechstes Bit ins Carry holen
ADCA #0 ; Carry zu A ddieren
TSTB ; Restwort = 0?
BNE ZHL ; nein, weiter
PULB ; Codewort holen
ASLB ; links schieben
LSRA ; Parity-Bit ins Carry
RORB ; Parity-Bit ins MSB vom Codewort
RTS
*
* Konvertierung Binär zu ASCII
* Parameter in Akku A
*
BINASC ANDA #0F ; auf Werte zwischen 0 und 15 begrenzen
CMPA #9 ; Wert 0 bis 9 ?
BLS ZIF ; ja, dann direkt umwandeln
ADDA #7 ; "A" - "9" - 1 = $41 - $39 - 1 = 7
ZIF ADDA #$30 ; $30 = "0" (ASCII-Wert)
RTS
*
* Unterprogramm ASCII-Binär-Konvertierung (0 - 9, A - F)
* Parameter in A
*
ASCBIN SUBA #$30 ; $30 = ASCII "0"
BLO FEHL ; Erg. negativ
keine Ziffer
CMPA #9 ; kleiner oder gleich 9?
BLS DONE ; dann fertig
SUBA #7 ; "A" - "F"
10 - 15
CMPA #10 ; kleiner als 10?
BLO FEHL ; dann Fehler
CMPA #15 ; größer 15?
BLS DONE ; nein, fertig
FEHL LDAA #$FF ; Fehlerflag setzen
DONE RTS
hx4a psha ; Akku A auf dem Stack ablegen
bsr hx2a ; Akku B umwandeln (Stelle 3 und 4)
pulb ; Akku A vom Stack holen, in Akku B ablegen
; Nun einfach in hx2a fallen und Akku B
; umwandeln (Stelle 1 und 2)
hx2a pshb ; Akku B aud dem Stack sichern
bsr hx1a ; Bits 0-3 von Akku B umwandeln
pulb ; Original-Akku B wieder holen
lsrb ; viermal schieben (Bits 4-7 --> 0-3)
lsrb
lsrb ; und nun die obere Haelfte umwandeln
lsrb ; indem einfach in hx1a gefallen wird
; Nun wird die eigentliche Arbeit gemacht:
hx1a andb #$0F ; die oberen 4 Bita ausmaskieren
addb #48 ; ASCII-Wert von "0" addieren
cmpb #57 ; groesser als "9"?
bls hx1b ; nein, dann speichern
addb #7 ; sonst die Distanz zwischen "9" und "a" addieren
hx1b stab 0,y ; Im Speicher ablegen, auf den Y zeigt
dey ; Y zeigt jetzt auf die Stelle davor
rts ; und weg
LDX #STRING ; Beginn der Zeichenkette
CHECK LDAA 0,X ; Zeichen lesen
INX ; X erhoehen
CHECK CMPA #$20 ; Leerzeichen?
BEQ CHECK ; Ja, weiter testen
DEX ; nein, Zeiger korrigieren
.
.
.
STRING DC.B ' Zeichenkette mit 4 Leerzeichen am Anfang'
DC.B 0 Abschlußzeichen
; Vergleich zweier Strings, Anfangsadressen in X und Y
; Ergebnis wird in Akku A zurueckgegeben (0: ungleich, FF: gleich)
vergl ldaa 0,X ; Zeichen aus String 1 vergleichen
cmpa 0,Y ; mit Zeichen aus String 2
bne ver0 ; Strings ungleich, fertig
cmpa #0 ; Stringende
beq ver1 ; Strings sind gleich, fertig
inx ; naechstes Zeichen
iny
bra vergl
ver1 ldaa #$ff
rts
ver0 clra
rts
delay pshx ; Register x retten, 4 cycl
ldx #$f211 ; Anfangswert laden, 3 cycl
delay1 nop ; 5 x nop = 10 cycl
nop
nop
nop
nop
dex ; X runterzaehlen, 3 cycl
bne delay1 ; 3 cycl
pulx ; Register restaurieren, 5 cycl
rts ; 5 cycl
delay clra ; Akku D: Akku A = 0, Akku B = Wert
andb #$0F
beq del_end ; Division durch 0 verhindern
ldx #$FF00 ; Wert fuer 1 Hz --> X
xgdx ; Schalter in X, 1-Hz-Wert in D
idiv ; D/X
delay1 nop
nop
nop
nop
nop
nop
nop
dex
bne delay1
del_end rts
org data
sek ds.b 1
zsek ds.b 1
org prog
main lds #stack ; Initialisierung
clr portb
ldaa #%11110000 ; Bits 0-3 als Eingang
staa ddrc
loop ldab portc ; Schalter einlesen
andb #$0F
lslb ; Akku B * 2, weil 16-Bit-Zugriff
; (jeweils 2 Byte)
ldx #tabelle ; Tabellenzugriff: X zeigt aus Tab.-Anfang
abx ; aktuelle Position: B + X
ldd 0,X ; Wert laden
std sek ; Sekunden in sek, 1/10 in zsek
jmp loop
* 0 1 2 3 4 5 6 7
tabelle dc.b 0,0, 2,5, 4,0, 10,0, 15,5, 20,0, 25,3, 31,4,
* 8 9 10 11 12 13 14 15
dc.b 40,0, 51,2, 60,0, 65,8, 72,4, 80,1, 85,7, 95,3
prog equ $8000 ; Vereinbarungen
data equ $2000
stack equ $7FFF
portb equ $1004
reset equ $fffe
org prog
main lds #stack
ldx #muster ; X verweist auf das erste Feldelement
loop ldaa 0,x ; erstes Feldelement laden
bne ausg ; wenn nicht 0, ausgeben
ldx #muster ; sonst wieder zum ersten Element
bra loop ; ohne Ausgabe
ausg staa portb ; Bitmuster ausgeben
jsr delay ; 0,5 s warten
inx ; naechstes Element
bra loop
delay pshx ; Delay, siehe oben
ldx #$f422
delay1 nop
nop
nop
nop
nop
dex
bne delay1
pulx
rts
muster dc.b %11110000, %01111000, %00111100, %00011110
dc.b %00001111, %00011110, %00111100, %01111000
dc.b %0
org reset ; Reset-Vektor setzen
fdb main
end

prog equ $8000
data equ $2000
stack equ $7FFF
portb equ $1004
reset equ $fffe
org data
count ds.b 1
org prog
main lds #stack
clr count ; Speicher loeschen
loop ldab count ; Schleifenbeginn, count mod 16 hochzaehlen
incb
andb #$0F
stab count
bsr umco ; Count in Akku B wird umcodiert, Ergebnis in Akku B
stab portb ; und ausgeben
jsr delay ; 0,5 s warten
bra loop
; Umcodierung binaer --> 7-Segment, eingabe und Ausgabe in Akku B
umco ldx #umcotab ; Tabellenadresse laden
andb #$0F ; fuer B nur Werte 0 - F zulassen
abx ; X = X + B
ldab 0,x ; 7-Sement-Wert holen, Adressierung durch X-Register
rts
delay pshx ; Delay, siehe oben
ldx #$f422
delay1 nop
nop
nop
nop
nop
dex
bne delay1
pulx
rts
; Siebensegment-Tabelle (Segmentanordnung: -abcdefg)
; Die Ziffern "0" bis "9" sind decodiert, fuer "A" bis "F"
; wird nur ein "-" angezeigt --> noch zu ergaenzen
umcotab dc.b %01111110, %00110000, %01101101, %01111001
dc.b %00110011, %01011011, %01011111, %01110000
dc.b %01111111, %01111011, %00000001, %00000001
dc.b %00000001, %00000001, %00000001, %00000001
org reset
fdb main
end
gets stx pufanf
gets0 bsr recv
cmpb #cr
beq gets1
cmpb #bs
beq gets2
cmpb #' ' ; Zeichen < ' ' ignorieren
blo gets0
bsr send
stab 0,x
inx
bra gets0
gets1 clrb ; Newline - Eingabeende
stab 0,x ; Nullbeit als Abschluss
bsr crlf ; cr + lf ausgeben
rts
gets2 cpx pufanf ; Backspace
beq gets0 ; nur bis Pufferanfanng zurück
dex
ldab #bs ; BS , Leer, BS ausgeben
bsr send
ldab #' '
bsr send
ldab #bs
bsr send
bra gets0
; cr+lf ausgeben
crlf ldab #cr
bsr send
ldab #lf
bsr send
rts
; Vereinbarungen
prog equ $8000
data equ $2000
stack equ $7FFF
portb equ $1004
portc equ $1003
portcl equ $1005
pioc equ $1002
ddrc equ $1007
scdr equ $102f
scsr equ $102e
sccr1 equ $102c
sccr2 equ $102d
baud equ $102b
reset equ $fffe
; ASCII-Zeichen
cr equ 13
lf equ 10
org prog
main lds #stack ; Initialisierungen
bsr sini
loop ldx #cmd ; Prompt ausgeben
bsr ssend
bsr recv ; Befehl (1 Zeichen) einlesen
cmpa #'a' ; ist es 'a'?
bne next1 ; nein, weiter
bsr doit ; Kommando 'a' verarbeiten
bra loop
next1 cmpa #'b' ; ist es 'b'?
bne next2 ; nein, weiter
bsr doit ; Kommando 'b' verarbeiten
bra loop
next2 cmpa #'c' ; ist es 'c'?
bne next3 ; nein, weiter
bsr doit ; Kommando 'c' verarbeiten
bra loop
next3 ldx #oops ; falsche Eingabe: "Oops" ausgeben
bsr ssend
bra loop
; Kommandobearbeitungsroutine, hier als Dummy
doit psha ; Kommandobearbeitung, erst Akku A retten
ldx #k1 ; Text "Eingabe war" ausgeben
bsr ssend
pula ; Akku A wiederherstellen
suba #$20 ; Kleinbuchstaben in Grossbuchstaben wandeln
bsr send ; ausgeben
bsr crlf ; "neue Zeile" ausgeben
rts
; Carriage Return und Line Feed ausgeben
crlf ldaa #cr
bsr send
ldaa #lf
bsr send
rts
; String ausgeben (ohne cr/lf am Ende), Stringadresse (erstes Zeichen)
; muss in Register X uebergeben werden (siehe Kapitel 5)
ssend ldaa 0,x
beq sfin
bsr send
inx
bra ssend
sfin rts
; serielle Schnittstelle initialisieren (siehe Kapitel 5)
sini clr sccr1
ldaa #$0C
staa sccr2
ldaa #$30
staa baud
rts
; Zeichen seriell ausgeben (siehe Kapitel 5)
send ldab scsr
bpl send
staa scdr
rts
; Zeichen seriell empfangen (siehe Kapitel 5)
recv ldab scsr
andb #$20
beq recv
ldaa scdr
rts
; String-Konstanten (Strings werden durch ein 0-Byte abgeschlossen)
cmd dc.b 'Kommando: '
dc.b 0
oops dc.b 'Oops!'
dc.b cr,lf,0
k1 dc.b 'Eingabe war '
dc.b 0
org reset ; Reset-Vektor setzen
fdb main
end
prog equ $8000
data equ $2000
stack equ $7FFF
portb equ $1004
portc equ $1003
ddrc equ $1007
reset equ $fffe
tvec equ $FFDE ; interrupt vector of timer
tmsk equ $1024 ; timer mask
tflg equ $1025 ; timer flag
pacr equ $1026 ; pulse accu control
org data
count ds.b 1
cflg ds.b 1
org prog
main lds #stack ; init variables
clr portb
clr count
clr cflg
ldab #$40 ; enable PA7 interrupt
stab pacr ; enable pulse accu
ldab #$80
stab tmsk
cli ; enable interrupts
loop ldaa cflg ; get clock flag
cmpa #20 ; trigger point?
bne loop ; no, wait
clr cflg ; yes, clear clock flag
inc count ; count up
ldaa count
staa portb ; display counter
bra loop
; interrupt service routine
tirq ldaa #$80
staa tflg ; clear interrupt
inc cflg ; count interrupts
rti
org tvec ; set interrupt vector
fdb tirq ; DE timer overflow
org reset ; set reset vector
fdb main
end
data equ $2000 ; data area (e-ram)
stak equ $7FFF ; stack area (e-ram)
prog equ $8000 ; programm area (e-eerom)
pvec equ $FFDA ; vector pa7
tvec equ $FFDE ; vector timer
svec equ $FFF2 ; sirq vector
rvec equ $FFFE ; reset vector
pioc equ $1002 ; parallel i/o control
pbdr equ $1004 ; port b data
portcl equ $1005 ; port c data latch
tmsk equ $1024 ; timer mask
tflg equ $1025 ; timer flag
pacr equ $1026 ; pulse accu control
***************************
* data area *
***************************
org data
flag ds.b 1 ; irq flag
***************************
* program area *
***************************
org prog
main lds #stak ; load stackpointer
bsr init ; data init
cli ; enable irq
loop ldaa flag
staa pbdr ; display
bra loop ; close main loop
***************************
* subroutines *
***************************
init clr flag
ldab #$40 ; enable STRA interrupt
stab pioc
rts
***************************
* interrupt handler *
***************************
sirq ldaa pioc ; stra isr
ldaa portcl ; clear interrupt
com flag
rti
***************************
* vectors *
***************************
org svec
fdb sirq ; STRA
org rvec
fdb main ; FE reset
end
data equ $2000 ; data area (e-ram)
stak equ $7FFF ; stack area (e-ram)
prog equ $8000 ; programm area (e-eerom)
pvec equ $FFDA ; vector pa7
tvec equ $FFDE ; vector timer
svec equ $FFF2 ; sirq vector
rvec equ $FFFE ; reset vector
pioc equ $1002 ; parallel i/o control
pbdr equ $1004 ; port b data
pcdl equ $1005 ; port c data latch
tmsk equ $1024 ; timer mask
tflg equ $1025 ; timer flag
pacr equ $1026 ; pulse accu control
baud equ $102B ; SCI-baudrate
sccr1 equ $102C ; SCI-control1
sccr2 equ $102D ; SCI-control2
scsr equ $102E ; SCI-status
scdr equ $102F ; SCI-data
***************************
* data area *
***************************
org data
flag ds.b 1 ; irq flag
***************************
* program area *
***************************
org prog
main lds #stak ; load stackpointer
bsr init ; data init
cli ; enable irq
loop ldaa flag
staa pbdr ; display
bra loop ; close main loop
***************************
* subroutines *
***************************
init clr flag
ldab #$40 ; enable STRA interrupt
stab pioc
ldab #$40 ; enable PA7 interrupt
stab pacr
ldab #$10
stab tmsk
rts
***************************
* interrupt handler *
***************************
sirq ldaa pioc ; stra isr
ldaa pcdl ; clear interrupt
ldaa flag
eora #$0F ; toggle lower nibble
staa flag
rti
pirq ldaa #$10 ; pa7 isr
staa tflg ; clear interrupt
ldaa flag
eora #$F0 ; toggle upper nibble
staa flag
rti
***************************
* vectors *
***************************
org pvec
fdb pirq ; PA7 interrupt
org svec
fdb sirq ; STRA
org rvec
fdb main ; FE reset
end
data equ $2000 ; data area (e-ram)
stak equ $7FFF ; stack area (e-ram)
prog equ $8000 ; programm area (e-eerom)
pvec equ $FFDA ; vector pa7
tvec equ $FFDE ; vector timer
svec equ $FFF2 ; sirq vector
rvec equ $FFFE ; reset vector
pioc equ $1002 ; parallel i/o control
pbdr equ $1004 ; port b data
pcdl equ $1005 ; port c data latch
tmsk equ $1024 ; timer mask
tflg equ $1025 ; timer flag
pacr equ $1026 ; pulse accu control
***************************
* data area *
***************************
org data
coun ds.b 1 ; counter
cflg ds.b 1 ; clock flag
updn ds.b 1 ; direction flag
stop ds.b 1 ; stop flag
***************************
* program area *
***************************
org prog
main lds #stak ; load stackpointer
bsr init ; data init
cli ; enable irq
loop ldaa cflg ; get clock flag
cmpa #20 ; trigger point?
bne loop ; no, wait
clr cflg ; yes, clear clock flag
tst stop ; stop active?
bne loop ; yes, wait
bsr count ; update counter
bra loop ; close main loop
***************************
* subroutines *
***************************
count ldaa coun ; load counter
adda updn ; inc/dec counter
staa coun ; save counter
staa pbdr ; display counter
rts
init clr coun ; counter default
clr cflg ; no clock seen
clr stop
ldaa #1
staa updn ; default count up
ldab #$40 ; enable STRA interrupt
stab pioc
ldab #$40 ; enable PA7 interrupt
stab pacr ; enable pulse accu
ldab #$90 ; $80 (Timer) + $10 (PA7)
stab tmsk
rts
***************************
* interrupt handler *
***************************
tirq ldaa #$80 ; timer isr
staa tflg ; clear interrupt
inc cflg ; count interrupts
rti
sirq ldaa pioc ; stra isr
ldaa pcdl ; clear interrupt
neg updn ; toggle direction
rti
pirq ldaa #$10 ; pa7 isr
staa tflg ; clear interrupt
com stop ; toggle stop flag
rti
***************************
* vectors *
***************************
org pvec
fdb pirq ; PA7
org tvec
fdb tirq ; timer overflow
org svec
fdb sirq ; STRA
org rvec
fdb main ; FE reset
end
Zum vorhergehenden Abschnitt |
Zum Inhaltsverzeichnis |
Zum nächsten Abschnitt |