Unterkapitel zur HTML-Seitenverkleinerung


;; (C) David Vajda
;; 2025-03-10
;; Pascal LED out

.include "m8def.inc"

.equ PASCAL_HEIGHT = 11
.equ PASCAL_WIDTH = 2*PASCAL_HEIGHT+1
.def    COL_COUNTER = r17
.def    ROW_COUNTER = r18

ldi r16, HIGH (RAMEND)
out SPH, r16
ldi r16, LOW (RAMEND)
out SPL, r16
ldi r16, 0xff
out DDRD, r16

main_loop:
rcall pasc_out
rjmp main_loop

sleep:
push r16
push r17
ldi r16, 0xff
sleep_loop1:
ldi r17, 0xff
sleep_loop2:
dec r17
brne sleep_loop2
dec r16
brne sleep_loop1
pop r17
pop r16
ret

pasc_out:
ldi COL_COUNTER, 0x00
ldi ROW_COUNTER, 0x00
ret

pasc_init0:
ldi r19, 0x00
ldi r16, HIGH (pascal)
mov XH, r16
ldi r16, LOW (pascal)
mov XL, r16
ldi COL_COUNTER, 0x00
pasc_init0_loop01:
ldi ROW_COUNTER, 0x00
pasc_init1_loop02:
st X+, r19
inc ROW_COUNTER
cpi ROW_COUNTER, PASCAL_HEIGHT
brne pasc_init1_loop02
inc COL_COUNTER
cpi COL_COUNTER, PASCAL_WIDTH
brne pasc_init0_loop01
ret

pasc_echo:
ldi COL_COUNTER, 0x00
ldi ROW_COUNTER, 0x00

ret

pasc_run:
ldi COL_COUNTER, 0x00
ldi ROW_COUNTER, 0x00

ret

.dseg

pascal: .byte  PASCAL_HEIGHT*PASCAL_WIDTH
Was mir jetzt fehlt also bei Byte kann ich jetzt jedes eins kann ich jetzt jeden einzelnen Wert reservieren aber wie auch beim sagen wir X6 achtziger gibt's ja auch verschiedene Syntaxuhren für nasm masm und tasm kann man ja sozusagen anstatt einzelne Werte zu reservieren. Ganzen Speicherbereich reservieren mit einer gewissen Größe und es muss ich jetzt hier auch machen im SRAM beim atmega8 da weiß ich jetzt nicht, wie das geht

https://www.roboternetz.de/community/threads/5931-ATmega16-und-Array

Hier steht es und zwar nicht in den ersten zwei Beiträgen. Die sind ein bisschen seltsam, sondern im Dritten. Ich zitiere ich poste den Inhalt. Das geht ganz einfach kurz und gut.

Man muss halt den variablen Namen für das Array nehmen im sram und dahinter 128 Schreiben zum Beispiel für ein Speicherbereich von 128 Byte


;sinnloser Code, nur als Beispiel

.cseg            ;im ROM

; ...
    ldi R16,0x25
    sts array+2,R16
    ldi R16, 0x44
    sts array+3,R16
;   ...
    lds r16,array+2
    ...
    lds r16,array+3
;   ...

.dseg          ;im RAM

array:         ;Label für das Array
.byte 100      ;100 bytes reservieren für das Array
So, jetzt klassischerweise muss ich natürlich  folgendes tun ich muss am, wenn man jetzt lds und sts als solchen nimmt kann man das beziehen auf das sozusagen Label oder die Marke von dem Speicherbereich nehmen also dem Feld wir müssen allerdings aufpassen jetzt weil wir haben's ja mit dem Feld zu tun d.h. mit Indiz und wir können jetzt nicht die Marke selber nehmen, sondern wir müssen die Zeiger X, Y, Z nehmen wir über die Register r31:r30, r29:r28, r27:r26 ansprechen, der Unterschied ist ich weiß bisher zwar wie es mit ld und st sowie ldd und std geht aber nicht mit lds und sts wahrscheinlich auf die selbe Art und Weise. Ich muss einfach die Zeiger richtig initialisieren und dann halt hinter des lds  als Operanden den entsprechenden Zeiger nehmen, vermute ich mal

Und um X und Y zu initialisieren, muss ich halt folgendes machen. Ich muss erst mal in r16 den oberen Teil der Adresse laden, vermute ich also HIGH(Label) dann ist es zum Beispiel Register und Register von X schreiben. X also XH und dann den unteren Teil LOW(Label) in Register r16 und dann das ganze nach XL und da muss ich ja nur noch nach oben zählen und dann müsste eigentlich fertig sein. Also nicht so schwierig. Probier mal aus


;; scheint schon mal so gut zu tun
;...
pasc_init0:
ldi r19, 0x00
ldi r16, HIGH (pascal)
mov XH, r16
ldi r16, LOW (pascal)
mov XL, r16
ldi COL_COUNTER, 0x00
pasc_init0_loop01:
ldi ROW_COUNTER, 0x00
pasc_init1_loop02:
st X+, r19
inc ROW_COUNTER
cpi ROW_COUNTER, PASCAL_HEIGHT
brne pasc_init1_loop02
inc COL_COUNTER
cpi COL_COUNTER, PASCAL_WIDTH
brne pasc_init0_loop01
ret

pasc_echo:
ldi COL_COUNTER, 0x00
ldi ROW_COUNTER, 0x00

ret

pasc_run:
ldi COL_COUNTER, 0x00
ldi ROW_COUNTER, 0x00

ret

.dseg

pascal: .byte  PASCAL_HEIGHT*PASCAL_WIDTH
da ist gleich mal ein fehler drin, ich habe st verwendet und muss sts verwenden. ob das ueberhaupt geht?

nein, da ist gleich mal ein fehler drin und in

https://www.mikrocontroller.net/articles/AVR-Tutorial:_SRAM#LDS

steht gucke ich nach sram (.dseg) in verbindung mit X, Y, Z Pointer, ausserdem, frage: was ist mit indizierter addressierung mit verschiebewert zu tun? weil ldd ist Y+5 OK, aber was mache ich bei sts und lds?

ok, in meinem falle relativiert sich das. ich habe ja die tabelle - und die ist voller 0en nur eine 1 muss am anfang oben in die mitte in der ersten zeile, aber - that's our label vom feld + eben der haelfte und so weiter, pro zeilenlaenge. das heisst, ich kann das zum label addieren.

ach so, jetzt habe ich es geschnallt, das ist ein genereller irrtum, gut dass ich die uebung mache, grosser fehler!

wenn ich auf eine speicherzelle - vermute ich - direkt zugreife, das heisst ueber einen konstanten wert - Label - direkte addressierung, dann nehme ich das Label - und sts und lds

ansonsten scheinen sts und lds ueberfluessig. ich habe X Y und Z Pointer bisher mit dem statischen Datenspeicher in Verbindung gebracht. Aber: ausserhalb der direkten addressierung - konstant, naemlich indirekt und indiziert, also ueber Zeiger, X, Y, Z findet wohl der Zugriff auf das SRAM genauso ueber die Zeiger und ld, ldd, st, std statt, wie beim statischen.

ldd und std geht nur bei Y und Z so ist richtig


;; (C) David Vajda
;; 2025-03-10
;; Pascal LED out

.include "m8def.inc"

.equ PASCAL_HEIGHT = 11
.equ PASCAL_WIDTH = 2*PASCAL_HEIGHT+1
.equ PASC_FRST = ((PASCAL_WIDTH>>1)+1)
.def    COL_COUNTER = r17
.def    ROW_COUNTER = r18

ldi r16, HIGH (RAMEND)
out SPH, r16
ldi r16, LOW (RAMEND)
out SPL, r16
ldi r16, 0xff
out DDRD, r16

main_loop:
rcall pasc_out
rjmp main_loop

sleep:
push r16
push r17
ldi r16, 0xff
sleep_loop1:
ldi r17, 0xff
sleep_loop2:
dec r17
brne sleep_loop2
dec r16
brne sleep_loop1
pop r17
pop r16
ret

pasc_out:
ldi COL_COUNTER, 0x00
ldi ROW_COUNTER, 0x00
ret

pasc_init0:
ldi r19, 0x00
ldi r16, HIGH (pascal)
mov XH, r16
ldi r16, LOW (pascal)
mov XL, r16
ldi COL_COUNTER, 0x00
pasc_init0_loop01:
ldi ROW_COUNTER, 0x00
pasc_init1_loop02:
st X+, r19
inc ROW_COUNTER
cpi ROW_COUNTER, PASCAL_HEIGHT
brne pasc_init1_loop02
inc COL_COUNTER
cpi COL_COUNTER, PASCAL_WIDTH
brne pasc_init0_loop01
ldi r16, HIGH (pascal)
mov YH, r16
ldi r16, LOW (pascal)
mov YL, r16
ldi r19, 0x01
std Y+PASC_FRST, r19
ret

pasc_echo:
ldi COL_COUNTER, 0x00
ldi ROW_COUNTER, 0x00

ret

pasc_run:
ldi COL_COUNTER, 0x00
ldi ROW_COUNTER, 0x00

ret

.dseg

pascal: .byte  PASCAL_HEIGHT*PASCAL_WIDTH