6502 - Programmbeispiel am LCD
Vollständiger Adressdekoder
Initialisierung und Anzeige auf dem LCD
- Ähnliches Timing des LCD wie bei RAM (PHI2 = H)
siehe http://www.6502.org/mini-projects/optrexlcd/lcd.htm
- Befehlsregister des LCD (RS=0): 0x7F10
- Datenregister des LCD (RS=1): 0x7F11
Initialisierung und Anzeige einer Zeichenkette
LCD_CMD = 0x7F10
LCD_DATA = 0x7F11
.org 0x8000
reset:
cli
ldx #$ff
txs
lda #0b00111000
sta LCD_CMD
lda #0b00001110
sta LCD_CMD
lda #0b00000110
sta LCD_CMD
lda #0b00000001
sta LCD_CMD
ldx #0
print_loop:
lda message,x
beq loop
sta LCD_DATA
inx
jmp print_loop
loop:
jmp loop
message:
.asciiz "Hello World!"
Auslesen der Busy-Flag
Auslesen der Busy-Flag: Subroutine
lda #0b00111000
jsr lcd_command
lda #0b00001110
jsr lcd_command
lda #0b00000110
jsr lcd_command
lda #0b00000001
jsr lcd_command
lcd_command:
sta LCD_CMD
lcd_wait:
lda LCD_CMD
and #0x80
bne lcd_wait
rts
Programmierung eines Zählers
- Auf Tastendruck soll eine Variable hochgezählt werden.
- Eine Anzeige dieser Zählervariable auf dem LCD.
Manipulation der Cursorposition und Anzeige von ASCII-Zeichen
- Um den Cursor des LCDs zu bewegen, muss die DDRAM-Adresse verändert werden.
- Zeile 1 beginnt mit Adresse 0x00, die Zeile 2 mit Adresse 0x40. Pro Spalte wird der Adresswert um 1 erhöht.
Anzeige vorlaufender ASCII-Zeichen
counter = 0x00
update = 0x01
LCD_CMD = 0x7F10
LCD_DATA = 0x7F11
LCD_GOTO_LINE1 = 0x80
LCD_GOTO_LINE2 = 0xC0
...
lda #32
sta counter
lda #1
sta update
...
loop:
lda update
beq loop
lda #LCD_GOTO_LINE1
jsr lcd_command
lda counter
sta LCD_DATA
lda #0
sta update
jmp loop
...
irq:
pha
lda IFR
and #CA1
beq exit_irq
inc counter
inc update
bit ORA
exit_irq:
pla
rti
Taster entprellen
Software-Verzögerung in der ISR zum Entprellen
irq:
pha
lda IFR
and CA1
beq exit_irq
ldx #0xFF
debounce_loop:
dex
bne debounce_loop
lda ORA
and #0x01
bne exit_irq
inc counter
inc update
exit_irq:
pla
rti
Darstellung als Binärzahl
- Schiebe-Anweisungen:
ASL
(Arithmetic Shift Left): C ← 7 6 5 4 3 2 1 0 ← 0
LSR
(Logical Shift Right): 0 → 7 6 5 4 3 2 1 0 → C
ROL
(Rotate Left): C ← 7 6 5 4 3 2 1 ← C
ROR
(Rotate Right): C → 7 6 5 4 3 2 1 → C
Anzeige des Zählers als Binärzahl auf dem LCD
counter = 0x00
update = 0x01
convertion = 0x02
number_buff = 0x03 ; 9 Byte
...
lda #0
sta counter
lda #1
sta update
lda #0
sta number_buff+8
...
loop:
lda update
beq loop
lda #LCD_GOTO_LINE1
jsr lcd_command
lda counter
sta convertion
ldx #8
convertion_loop:
; Modulo
lda #1
and convertion
adc #48
sta number_buff-1,x
; /2
lsr convertion
dex
bne convertion_loop
ldx #0
print_loop:
lda number_buff,x
beq exit_print_loop
sta LCD_DATA
inx
jmp print_loop
exit_print_loop:
lda #0
sta update
jmp loop
...
Darstellung als Hexadezimalzahl
Anzeige des Zählers als Hexadezimalzahl auf dem LCD
...
loop:
lda update
beq loop
lda #LCD_GOTO_LINE1
jsr lcd_command
lda counter
clc
lsr
clc
lsr
clc
lsr
clc
lsr
jsr lcd_print_nibble
lda counter
and #0xF
jsr lcd_print_nibble
lda #0
sta update
jmp loop
lcd_print_nibble:
cmp #10
bpl lcd_print_nibble_letter
clc
adc #48
sta LCD_DATA
rts
lcd_print_nibble_letter:
clc
adc #55
sta LCD_DATA
rts
Darstellung als BCD-Zahl
- BCD = binary coded decimal
- Jeweils eine Dezimalziffer wird durch exakt 4 Bits dargestellt.
Darstellung im BCD-Format
Dezimalzahl | BCD |
---|---|
0 | 0000 0000 |
1 | 0000 0001 |
2 | 0000 0010 |
... | ... |
9 | 0000 1001 |
10 | 0001 0000 |
11 | 0001 0001 |
12 | 0001 0010 |
... | ... |
19 | 0001 1001 |
20 | 0010 0000 |
... | ... |
99 | 1001 1001 |
- Setzen des Decimal-Bits im Status-Register
- Zugehörige Anweisungen:
SED
Set Decimal Mode
CLD
Clear Decimal Mode - Der Decimal Mode funktioniert nur mit den beiden Anweisungen
ADC
undSBC
.
Inkrementieren der Zählervariable als BCD