Hallo Forumgemeinde, hallo Rolf,
ich möchte einen Device Treiber für Write schreiben. Im Handbuch steht dazu
Wie schon o.a. kann Write auch selbstdefinierte Gerätetreiber ansprechen. Hierbei sind jedoch einige Besonderheiten zu beachten:
Diese Prozedur muss einen Übergabe-Parameter vom Typ Byte oder Char besitzen, sie darf keine lokalen Variablen besitzen und damit auch keinen Frame. Weiterhin dürfen innerhalb der Prozedur nur die PseudoAccus “_ACCA, _ACCB, _ACCCHI und _ACCCLO = Z” benutzt werden was einen Aufruf von anderen Prozeduren und Funktionen sowie von Systemfunktionen ausschliesst.
Sollten trotzdem zusätzliche ACCUs für Zwischenspeicher gebraucht werden, sind diese vorher mittels Push/Pop zu retten. Diese Einschränkungen erzwingen in der Praxis, dass diese Prozedur komplett in Assembler zu schreiben ist. Der Übergabe Parameter befindet sich in _ACCA. Wichtig ist der CompilerSchalter {$NOFRAME} oder {$DEVICE}.
Mich irritiert, dass eine Funktion mit vorangestelltem Compilerschalter {$DEVICE} oder {$NOFRAME} den Funktionsparameter aus dem _ACCA Register auf den den Frame legt (siehe Code), obwohl das Handbuch die Verwendung des Frames verbietet.
Fragen:
Darf ich Pascal-Code für einen Device Treiber für Write verwenden?
Wieso legt die mit {$DEVICE} kompilierte Funktion, den Parameter aus _ACCA auf den Frame?
Ich hoffe, meine Frage ist verständlich und danke sehr für eine Antwort.
------------------------------
Code:
Pascal
program TutorDemo;
Device = mega8, VCC = 5;
Import Serport;
From System Import;
Define
procClock = 8000000;
StackSize = 64, iData;
FrameSize = 64, iData;
Serport = 19200;
Implementation
{$IDATA}
{$DEVICE}
procedure myDevice(c : byte);
begin
Serout(c);
end;
begin
Writeln(myDevice, 'Hallo');
loop
endloop;
end.
Assembler
.FUNC myDevice, 00014h, 00020h
TutorDemo.myDevice:
.RETURNS 0
SBIW _FRAMEPTR, 1
STD Y+000h, _ACCA
.BLOCK 21
.LINE 22
LDD _ACCA, Y+000h
.FRAME 0
RCALL SYSTEM.SEROUT
.ENDBLOCK 23
TutorDemo.myDevice_X:
.LINE 23
ADIW _FRAMEPTR, 1
.BRANCH 19
RET
.ENDFUNC 23
Im Assemblercode Verwendung vom Framepointer
ich möchte einen Device Treiber für Write schreiben. Im Handbuch steht dazu
Quote
Wie schon o.a. kann Write auch selbstdefinierte Gerätetreiber ansprechen. Hierbei sind jedoch einige Besonderheiten zu beachten:
Diese Prozedur muss einen Übergabe-Parameter vom Typ Byte oder Char besitzen, sie darf keine lokalen Variablen besitzen und damit auch keinen Frame. Weiterhin dürfen innerhalb der Prozedur nur die PseudoAccus “_ACCA, _ACCB, _ACCCHI und _ACCCLO = Z” benutzt werden was einen Aufruf von anderen Prozeduren und Funktionen sowie von Systemfunktionen ausschliesst.
Sollten trotzdem zusätzliche ACCUs für Zwischenspeicher gebraucht werden, sind diese vorher mittels Push/Pop zu retten. Diese Einschränkungen erzwingen in der Praxis, dass diese Prozedur komplett in Assembler zu schreiben ist. Der Übergabe Parameter befindet sich in _ACCA. Wichtig ist der CompilerSchalter {$NOFRAME} oder {$DEVICE}.
Mich irritiert, dass eine Funktion mit vorangestelltem Compilerschalter {$DEVICE} oder {$NOFRAME} den Funktionsparameter aus dem _ACCA Register auf den den Frame legt (siehe Code), obwohl das Handbuch die Verwendung des Frames verbietet.
Fragen:
Darf ich Pascal-Code für einen Device Treiber für Write verwenden?
Wieso legt die mit {$DEVICE} kompilierte Funktion, den Parameter aus _ACCA auf den Frame?
Ich hoffe, meine Frage ist verständlich und danke sehr für eine Antwort.
------------------------------
Code:
Pascal
Code
program TutorDemo;
Device = mega8, VCC = 5;
Import Serport;
From System Import;
Define
procClock = 8000000;
StackSize = 64, iData;
FrameSize = 64, iData;
Serport = 19200;
Implementation
{$IDATA}
{$DEVICE}
procedure myDevice(c : byte);
begin
Serout(c);
end;
begin
Writeln(myDevice, 'Hallo');
loop
endloop;
end.
Assembler
Code
.FUNC myDevice, 00014h, 00020h
TutorDemo.myDevice:
.RETURNS 0
SBIW _FRAMEPTR, 1
STD Y+000h, _ACCA
.BLOCK 21
.LINE 22
LDD _ACCA, Y+000h
.FRAME 0
RCALL SYSTEM.SEROUT
.ENDBLOCK 23
TutorDemo.myDevice_X:
.LINE 23
ADIW _FRAMEPTR, 1
.BRANCH 19
RET
.ENDFUNC 23
Im Assemblercode Verwendung vom Framepointer