first commit

This commit is contained in:
Johannes Theiner 2018-09-26 21:54:09 +02:00
commit 0a36a1ef0e
27 changed files with 956 additions and 0 deletions

32
examples/asm/addit.asm Normal file
View File

@ -0,0 +1,32 @@
; ADDIT: ASM-Beispiel zur Addition mit dem SBC86
; C.Koch | 03.11.2010
org 100h
cpu 8086
START: mov ax,1
mov dx,1 ; Summand 1: dx:ax = 00010001h
mov bx,nVal32 ; Summand 2: Speicher
call AddNow
mov word [nResult],ax ; Ergebnis im Speicher ablegen
mov word [nResult+2],dx
jmp START
AddNow:
add ax, word [bx]
adc dx, word [bx+2] ; Addiere mit CF!
; alternative Speicheradressierung:
; add bx,2 ; Zeiger verstellen
; adc dx, word [bx] ; Addiere mit CF! - fkt. das?
ret ; Unterfunktion verlassen
nVal32 dd 0012ABCDh ; Adresse? Wert=
nResult dd 0 ; Adresse? Wert=
sText db 'Hier koennte Ihre Werbung stehen'

BIN
examples/asm/addit.com Normal file

Binary file not shown.

30
examples/asm/divit.asm Normal file
View File

@ -0,0 +1,30 @@
; ADDIT: ASM-Beispiel zur Division mit dem SBC86
; C.Koch | 03.11.2010
org 100h
cpu 8086
START:
; **** Byte-Division ****
mov ax,4522 ; Dividend ist immer das AX-Register (16 Bit)
mov bh,120 ; Divisor sei ein Wert in BH (8 Bit)
div bh ; AX/BH = Quotient in AL, Ganzzahlrest in AH
mov byte [nErgebnis],al ; Quotient -> Speicher
mov byte [nRest],ah ; Ganzzahlrest -> Speicher
; **** Wort-Division ****
mov dx, 0 ; Dividend ist immer das RegisterPAAR DX:AX (32 Bit)
mov ax,45220 ; Dividend, Bit 0...15
mov bx,120 ; Divisor sei ein Wert in BX (16 Bit)
div bx ; (DX:AX)/BX = Quotient in AX, Rest in DX
mov word [nErgebnis],ax ; Quotient -> Speicher
mov word [nRest],dx ; Ganzzahlrest -> Speicher
jmp START
nErgebnis dw 0 ; Adresse? Wert=
nRest dw 0 ; Adresse? Wert=
sText db 'Hier koennte Ihre Werbung stehen'

BIN
examples/asm/divit.com Normal file

Binary file not shown.

11
examples/asm/switch.asm Normal file
View File

@ -0,0 +1,11 @@
; SWITCH: ASM-Beispiel zur Benutzung der Ports des SBC86
; C.Koch | 28.10.2010
org 100h
cpu 8086
SWITCH: in al,00h ; Schalter abfragen
out 00h, al ; LEDs ansteuern
jmp SWITCH ; Endlosschleife

BIN
examples/asm/switch.com Normal file

Binary file not shown.

View File

@ -0,0 +1,26 @@
# Makefile zum Verlinken eines ASM-Moduls mit einem C-Programm
# HS Emden/Leer | C.Koch
# 11.06.2012 initial version
# 11.12.2014 update 64-bit. Ubuntu 14.04 -> to compile 32-bit code on 64-bit environment:
# $ sudo apt-get install gcc-multilib
# C-Quellcode kompilieren und mit ASM-Modul linken
callecho: echo.o callecho.o
gcc -m32 -o callecho callecho.o echo.o # linken
callecho.o: callecho.c
gcc -m32 -c -o callecho.o callecho.c # compilieren
# ASM-Modul assemblieren
echo.o: echo.asm
nasm -f elf -o echo.o echo.asm
# Projekt aufraemen
clean:
@echo 'Ausgabedateien loeschen'
rm -f callecho *.o *~

Binary file not shown.

View File

@ -0,0 +1,31 @@
/*
callecho.c
Demo: C und Assembler verlinken
HS Emden/Leer | C.Koch
07.06.2013 initial version
11.12.2014 minor changes
*/
#include <stdio.h>
extern int _echo(int);
short a;
int main(void)
{
short *p;
printf(" -- C+Assembler: Echo --\n");
a = 0x10;
printf("Rueckgabe: 0x%04x\n", _echo(a) );
return 0;
};
/* Ausgabe der Symbole der Objekt-Module:
cko@geo:echo$readelf -s echo.o
cko@geo:echo$readelf -s callecho.o
cko@geo:echo$readelf -s callecho
*/

Binary file not shown.

View File

@ -0,0 +1,36 @@
; echo.asm
; Demo: C und Assembler verlinken
; HS Emden/Leer | C.Koch
; 31.05.2013 initial version
; 11.12.2014 local variables added
; **** Code-Segment ****
section .text
global _echo
_echo:
push ebp ; neuer Stackframe: BasePointer retten
mov ebp,esp ; Stackpointer zum neuen BasePointer machen
sub esp, 4 ; ?
mov [ebp-4], word 1
mov eax,0 ; Rueckgabewert zur C-Funktion: EAX-Register
add ax, word [foo] ; ?
add ax, word [ebp+8] ; Parameter holen
add ax, word [ebp-4] ; ?
mov esp, ebp ; ?
pop ebp ; BP wiederherstellen
ret ; um die Uebergabeparameter kuemmert sich
; das rufende Programm (add esp, 16)
; **** Daten-Segment ****
section .data
; GLOBALE Variable anlegen und initialisieren.
; C-Beispiel: short foo = 0;
foo dw 2

Binary file not shown.

31
examples/c/tp-clswap.c Normal file
View File

@ -0,0 +1,31 @@
/*
clspwap.c: TecPro Beispielprogramm
Kurzbeschreibung: Sortieren der Kommandozeile
Version mit Vektorelementen
D. Ertelt, gccC.Koch | HS-Emden-Leer | 18.12.2010
*/
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) { /* **argv */
int i, j; /* Schleifenzaehler*/
char *tmp;
/* Ist String i mit j identisch? Nein? Dann vertauschen. */
for(i=1; i<argc ; i++)
for(j=i+1; j<argc ; j++)
/* strcmp: Rückgabe NULL -> Strings sind identisch
Rückgabe > 0 -> das erste nicht identische Zeichen des String hat einen größeren Wert */
if(strcmp(argv[i],argv[j]) > 0)
{ tmp=argv[j]; argv[j]=argv[i]; argv[i]=tmp; }
/* Ausgabe der Parameter - alphabetisch sortiert */
for(i=1; i<argc ; i++)
printf("%s ", argv[i]);
printf("\n");
}

34
examples/c/tp-enum.c Normal file
View File

@ -0,0 +1,34 @@
/*
tp-enum.c: TecPro Beispielprogramm
Kurzbeschreibung: eigene Datentypen als Aufzählung mit typedef
C.Koch | HS-Emden-Leer | 25.11.2010
HINWEIS: Wenn eine Variable mit enum definiert wird, behandelt sie
der Compiler als Integerzahl. Sie kann dann jeden Wert annehmen,
nicht nur die in enum festgelegten.
*/
#include <stdio.h> // diverse Standard-Input-Output-Funktionen
// neuen Datentyp deklarieren und definieren
typedef enum { ROT=1, ROTGELB, GRUEN, GELB } eAmpelzustand;
main()
{
eAmpelzustand ampel; // Variable deklarieren
printf("\nHallo Ostfriesland!\n"); // Ausgabe einer Zeichenkette
ampel = ROT;
printf("Status: %u\n", ampel);
ampel = ROTGELB;
printf("Status: %u\n", ampel);
ampel = GRUEN;
printf("Status: %u\n", ampel);
//ampel = SCHWARZ;
//printf("Status: %u\n", ampel);
}

37
examples/c/tp-enumB.c Normal file
View File

@ -0,0 +1,37 @@
/*
tp-enum.c: TecPro Beispielprogramm
Kurzbeschreibung: eigene Datentypen als Aufzählung - Ampelsteuerung
C.Koch | HS-Emden-Leer | 25.11.2010
HINWEIS: Wenn eine Variable mit enum definiert wird, behandelt sie
der Compiler als Integerzahl. Sie kann dann jeden Wert annehmen,
nicht nur die in enum festgelegten.
*/
#include <stdio.h> // diverse Standard-Input-Output-Funktionen
// neuen Datentyp definieren
enum eAmpelsteuerung { ROT=1, ROTGELB, GRUEN, GELB };
main()
{
//eAmpelzustand ampel; // Variable deklarieren
enum eAmpelsteuerung ampel;
printf("\nHallo Ostfriesland!\n"); // Ausgabe einer Zeichenkette
ampel = ROT;
printf("Status: %u\n", ampel);
ampel = ROTGELB;
printf("Status: %u\n", ampel);
ampel = GRUEN;
printf("Status: %u\n", ampel);
//ampel = SCHWARZ;
//printf("Status: %u\n", ampel);
printf("Modulo %u von %u ergibt %u.\n",20,3,20%3);
}

55
examples/c/tp-file.c Normal file
View File

@ -0,0 +1,55 @@
/*
tp-file.c: TecPro Beispielprogramm
Kurzbeschreibung: Die Standard C-Bibliothek
C.Koch | HS-Emden-Leer | 06.04.2011
Compile: gcc -g -Wall -o tp-file tp-file.c
Analyse: ddd tp-file
*/
#include <stdio.h>
#include <string.h>
void FileWrite(char* sInput);
int main(void)
{
char sInput[100];
int iTest= 64;
printf("\n ---- Die Standard C-Bibliothek stdio ----\n");
printf("iTest: \t %d %p %x %c\n",iTest, &iTest, iTest, iTest);
printf("-> Eingabe: ");
gets(sInput);
puts(sInput);
/* einfache String-Analyse zum bedingten Sprung via strcmp */
if(strcmp(sInput,"exit"))
FileWrite(sInput);
return 0;
}
/* Demo-Funktion zur Verwendung von Dateien */
void FileWrite(char* sInput)
{
FILE* fpDatei; /* "Handle" zur Adressierung von Dateien: File-Pointer */
int iLoop;
puts("-> Schreibe Eingabe in Datei 'out.txt' ");
/* Datei öffnen und via fprintf beschreiben*/
fpDatei = fopen("out.txt","w");
fprintf(fpDatei," ---- Demo-Datei ----\n Die Eingabe lautete: *%s*\n",sInput);
for(iLoop=0x20; iLoop<=0x40; iLoop++)
fprintf(fpDatei," iLoop: \t %03d %03x %c\n",iLoop, iLoop, (char) iLoop);
/* nach Bearbeitung die Datei wieder schließen */
fclose(fpDatei);
}

62
examples/c/tp-heap.c Normal file
View File

@ -0,0 +1,62 @@
/*
tp-heap.c: TecPro Beispielprogramm
Kurzbeschreibung: Zeichenketten in C und dynamische Speicherverwaltung
C.Koch | HS-Emden-Leer | 12.04.2011
Compile: gcc -g -Wall -o tp-heap tp-heap.c
Analyse: ddd tp-heap
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h> /* z.B. dynamische Speicherverwaltung via calloc() */
#define DYNMEM 32*1024*1024 /* Größe des dynamischen Speicherbereichs definieren */
void FileWrite(char* sInput);
int main(void)
{
/* Speicher auf dem Stack ist schnell adressiert,
jedoch pro Applikation nur begrenzt verfügbar (siehe $ ulimit -a) */
/* Beispiel: Textdatei einlesen */
/* Dateigröße? 8 kByte / 8MByte / 80 MByte? */
char cTextA[8*1024]; /* STACK */
char *cTextB;
FILE* fpDatei;
char *cStatus;
int iSize;
cTextB = calloc(DYNMEM,sizeof(char)); /* HEAP */
/* Programm abbrechen, falls ein Fehler
bei der Speicherallozierung auftritt*/
if(cTextB == NULL)
{
printf("-> FEHLER: Speicherallozierung nicht erfolgreich!\n");
return -1;
}
printf("\nDynamischer Speicher: %d kByte @ %p - %p\n", (DYNMEM * sizeof(char))/1024, cTextB, cTextB+(DYNMEM * sizeof(char)) );
/* Datei öffnen und zeilenweise auslesen */
fpDatei = fopen("tp-file/out.txt","r");
do
{
cStatus = fgets(cTextA, 100, fpDatei);
/* Länge des gelesenen Strings ermitteln */
iSize = strlen(cTextA);
cTextA[iSize-1]='*';
sprintf(cTextB,"%03u Zeichen -> %s |",iSize, cTextA);
puts(cTextB);
getchar();
}while(cStatus != NULL);
/* Datei wieder schließen und Speicher freigeben*/
fclose(fpDatei);
free(cTextB);
return 0;
}

35
examples/c/tp-local.c Normal file
View File

@ -0,0 +1,35 @@
/*
tp-local.c: TecPro Beispielprogramm
Kurzbeschreibung: lokale Datenobjekte / Gültigkeit
C.Koch | HS-Emden-Leer | 25.11.2010
*/
#include <stdio.h>
void main(void)
{
int myObj;
int* myObjPtr;
myObj = 20;
myObjPtr = &myObj;
/* Zugriff auf beliebige Adressen - was passiert?*/
/* myObjPtr = (int*) 0x55555; */
*myObjPtr = 10;
printf("->> Wert myObj \t: %i", myObj);
int a = 5;
{
int a = 20;
a++;
}
/* Welcher Wert wird ausgegeben - 5 oder 20 oder ... ?*/
printf("\n->> Wert a \t: %d\n",a);
}

54
examples/c/tp-printf.c Normal file
View File

@ -0,0 +1,54 @@
/*
tp-printf.c: Beispielprogramm HnP
Kurzbeschreibung: stdlib C, printf() und Bitmanipulation
C.Koch | HS-Emden-Leer
19.04.2013 Initialversion
07.11.2014 Erweiterung mit Datentypgröße und 32/64-Bit
Compile: gcc -o tp-printf tp-printf.c 64-Bit
gcc -m32 -o tp-printf tp-printf.c 32-Bit
Exec info: objdump -f tp-printf
*/
#include <stdio.h>
int main(void)
{
int i = -1;
char string[] = "+++ Hallo Ostfriesland +++";
char *p = string;
printf("1: %s \n",p);
printf("2: %u \n",i);
printf("3: %c \n",i);
printf("4: 0x%x \n\n",i);
printf("5: 0x%lx \n", (unsigned long) (&i));
printf("6: 0x%lx \n", (unsigned long) (&main));
printf("7: 0x%x \n",(unsigned int) ((unsigned long) (&i) & 0xffff));
printf("\n sizeof i: %i | p: %i\n", (int) sizeof(i), (int) sizeof(p));
return(0);
}
/* Beispielausgabe (32-Bit):
linfan@camaro:~/.../beispieleC$ ./tp-printf
1: +++ Hallo Ostfriesland +++
2: 4294967295
3: <EFBFBD>
4: 0xffffffff
5: 0xffbcc808
6: 0x804846d
7: 0xc808
sizeof i: 4 | p: 4
*/

22
examples/c/tp-pvec.c Normal file
View File

@ -0,0 +1,22 @@
/*
tp-pvec.c: TecPro Beispielprogramm
Kurzbeschreibung: Zeiger und Vektoren
D.Ertelt, C.Koch | HS-Emden-Leer | 25.11.2010
*/
#include <stdio.h>
int main(void) {
unsigned int a[6], i, *aPtr;
printf("Vorher: aPtr = 0x%08x &a = 0x%08x\n", aPtr, &a);
for(i=0; i < 6; i++)
printf("a[%d] = %d\n", i, a[i]);
printf("Nachher: aPtr = 0x%08x\n", (aPtr = a));
for( ; aPtr < a + 6 ; aPtr++) {
*aPtr = i--;
printf("*(0x%08x) = %d\n", (aPtr), *aPtr); }
}

20
examples/c/tp-regval.c Normal file
View File

@ -0,0 +1,20 @@
/*
tp-regval.c: TecPro Beispielprogramm
Kurzbeschreibung: Beispiel zum Adressoperator
C.Koch | HS-Emden-Leer | 19.12.2010
*/
/* Frage: Welche Funktion hat das Typattribut "register" ?
Wie wirkt es sich auf die Adressierung von Vaiablen aus? */
register int nTestVal;
int* pnZeiger;
void* pvZeiger; /* Frage: Was ist ein VOID-Pointer? Wie benutze ich ihn? */
void main(void)
{
nTestVal = 0xF0;
pnZeiger = &nTestVal;
}

41
examples/c/tp-sizeof.c Normal file
View File

@ -0,0 +1,41 @@
/*
tp-sizeof.c: TecPro Beispielprogramm
Kurzbeschreibung: Beispiel zur Strukturgroesse einzelner Datentypen
C.Koch | HS-Emden-Leer | 19.12.2010
*/
#include <stdio.h>
/* globale Datenobjekte deklarieren */
int cText[20];
int *pText;
typedef enum {NOKIA, SAMSUNG, LG, MOTOROLA, APPLE} eHandy;
typedef struct {eHandy Type; int Anzahl; char cLand[20];} stHersteller;
int main(void)
{
/* lokale Datenobjekte deklarieren */
stHersteller neuerHersteller;
unsigned char ucBytes;
pText = cText;
/* groessen berechnen */
ucBytes = sizeof(char);
printf("Anzahl Bytes: %u \n", ucBytes);
ucBytes = sizeof(pText);
printf("Anzahl Bytes: %u \n", ucBytes);
ucBytes = sizeof(eHandy);
printf("Anzahl Bytes: %u \n", ucBytes);
ucBytes = sizeof(neuerHersteller);
printf("Anzahl Bytes: %u \n", ucBytes);
/* Rueckgabewert an das Betriebssystem */
return (0);
}

60
examples/c/tp-swap.c Normal file
View File

@ -0,0 +1,60 @@
/*
tp-swap.c: TecPro Beispielprogramm
Kurzbeschreibung: "call by reference / call by value"
C.Koch | HS-Emden-Leer | 19.12.2010
*/
#include <stdio.h>
int swapRef(int* a, int* b);
int swapVal(int a, int b);
int swapMem(int* a, int* b);
void main(void)
{
/* auto -> Stack | static -> Datensegment*/
static int a,b;
a = 10; b = 20;
swapVal(a,b);
printf("Var \t a =%i \t b= %i \n",a, b);
swapRef(&a, &b);
printf("Var \t a =%i \t b= %i \n",a, b);
swapMem(&a, &b);
printf("Var \t a =%i \t b= %i \n",a, b);
}
int swapRef(int* a, int* b)
{
int temp;
temp = *a;
*a = *b; *b = temp;
return temp;
}
int swapVal(int a, int b)
{
int temp;
temp = a;
a = b; b = temp;
return temp;
}
/* Aufgabe: Wie muss die folgende Funktion geändert werden,
falls die Variablen a und b auf dem Stack liegen und nicht im Datensegment? */
int swapMem(int* a, int* b)
{
int temp;
temp = *a;
*a = *(a+1); *(a+1) = temp;
return temp;
}

17
general/a1.asm Normal file
View File

@ -0,0 +1,17 @@
org 100h
cpu 8086
jmp START
BYTE1 db 32
db 'Hardwarenahes Programmieren'
times 4 db 0,'1'
dw 1,2,3,4,1234
dd 1234h
START: mov bx, BYTE1
WDH: mov al, [bx]
out 0, al
inc bx
jmp WDH

186
general/a4.asm Normal file
View File

@ -0,0 +1,186 @@
org 100h
cpu 8086
jmp start
; Variablen
sollwert db tmin
tcounts db 0 ; Impulszaehler fuer Servo, Vorwaertszaehler
anzeige times 3 db 0 ; Puffer fuer Ausgabe
strlen equ $ - anzeige ; Laenge Zeichenpuffer
; Konstanten
intab0 equ 20h ; Adresse Interrupttabelle PIT, Kanal 1
eoi equ 20h ; End Of Interrupt (EOI)
clrscr equ 0 ; Clear Screen
getkey equ 1 ; Funktion auf Tastatureingabe warten
ascii equ 1 ; Funktion ASCII-Zeichenausgabe
hexbyte equ 4 ; HEX-Byte Ausgabe
conin equ 5 ; Console IN
conout equ 6 ; Console OUT
pitc equ 0a6h ; Steuerkanal PIT
pit1 equ 0a2h ; Counter 1 PIT
pit2 equ 0a4h ; Counter 2 PIT
ppi_ctl equ 0b6h ; Steuerkanal PPI (Parallelinterface)
ppi_a equ 0b0h ; Kanal A PPI
ppi_pa0 equ 1 ; LED 0
ppi_pa1 equ 2 ; LED 1
ppi_pa2 equ 4 ; LED 2
ppi_pa3 equ 8 ; Lautsprecher
ppi_pa6 equ 1 << 6 ; Servomotor
ppi_b equ 0b2h ; Kanal B PPI
ppi_c equ 0b4h ; Kanal C PPI
ocw_2_3 equ 0c0h ; PIC (Interruptcontroller), OCW2,3
ocw_1 equ 0c2h ; PIC (Interruptcontroller), OCW1
icw_1 equ 0c0h ; PIC (Interruptcontroller), ICW1
icw_2_4 equ 0c2h ; PIC (Interruptcontroller), ICW2,4
leds equ 0 ; LED Port
schalter equ 0 ; Schalterport
keybd equ 80h ; SBC-86 Tastatur
gokey equ 11h ; Taste "GO"
outkey equ 15h ; Taste "OUT"
sseg7 equ 9eh ; Segmentanzeige 7
tcpwm equ 184 ; 1843200 Hz / 184 = ca. 10000 Hz = 0.1 ms
; Taktzyklus
; Zeitkonstante fuer PWM-Interrupt
tpwm equ 200 ; Periodendauer des PWM-Signals (* 0.1 ms)
tmax equ 25 ; Impulsdauer fuer 0 Grad (* 0.1 ms)
tmin equ 6 ; Impulsdauer fuer 180 Grad (* 0.1 ms)
divider equ 13 ; Vorteiler Wandlerwert
; 0..255 -> 0..19 -> + tmin -> tmin..tmax
ad_start1 equ 00110000b ; AD-Wandler starten und auf "read"
ad_start2 equ 00100111b ; AD-Wandler nur "read" und LED's an
start:
; Initialisierung
mov ah, clrscr ; Anzeige aus
int conout
call init ; Controller und Interruptsystem scharfmachen
mov al, 0
out leds, al
mov al, ad_start1 ; ADU init.
out ppi_a, al
mov al, ad_start2
out ppi_a, al
; Hintergrundprogramm: Lesen des Wandlerwertes, Verarbeitung und Displayausgabe
again:
in al, ppi_b ; Wandlerwert
; ...
; ...
; ...
jmp again
; Ausgabe einer ASCII-Zeichenkette
strout:
; ...
; ...
; ...
ret
; 8-Bit Division AL / BL
; Return: Quotient in AL, Rest in AH
; Zerstoert AX, BH
; Algorithmus siehe:
; https://www-user.tu-chemnitz.de/~heha/Mikrocontroller/Division.htm
; Wuerde auch mit dem DIV-Befehl der CPU funktionieren, wieso dann das hier?
divide: xor ah, ah ; High-Teil Dividend
mov bh, 8 ; Anzahl Bits Quotient
_div: shl ax, 1 ; Dividend * 2
cmp ah, bl ; teilbar?
jb _smaller ; nein
sub ah, bl ; ja, abziehen
inc al ; Dividend, Bit 0 = 1
_smaller:
dec bh ; fertig?
jnz _div ; nein, naechste Stelle
ret
; Hornerschema rueckwaerts (Teilen des Wertes durch die Zielbasis bis nix mehr
; da ist; die Reste der Division sind die Ziffern, von "hinten" (LOW) beginnend)
; Hexwert (in AL) nach dezimal (ASCII-String) wandeln und in "anzeige" speichern
; Zerstoert AX, BX, CX, DI
val2astr:
mov di, anzeige + strlen - 1 ; Zielpuffer rueckwaerts beschreiben
mov bl, 10 ; Dezimalwandlung (Zielbasis)
xor cx, cx
v1: call divide ; AL / BL, Rest in AH
add ah, '0' ; --> ASCII
mov [di], ah ; Zeichen in Puffer
dec di ; vorherige Pufferstelle
inc cl ; Zaehler++
or al, al ; fertig? (Dividend zerdividiert?)
jnz v1 ; noe, nochmal
mov al, cl ; Anzahl
mov cl, strlen ; max. Stringlaenge
sub cl, al ; Anzahl Reststellen
; out leds, al ; Kontrollausgabe
jcxz v3 ; fertig?
v2: mov byte [di], ' ' ; Rest loeschen
dec di
loop v2 ; fertig?
v3: ret
; Initialisierung Controller und Interruptsystem
init:
cli ; Interrupts aus
; PIT-Init.
mov al, 01110110b ; Kanal 1, Mode 3, 16-Bit ZK
out pitc, al ; Steuerkanal
mov al, tcpwm & 0ffh ; Low-Teil Zeitkonstante
out pit1, al
mov al, tcpwm >> 8 ; High-Teil Zeitkonstante
out pit1, al
; PPI-Init.
mov al, 10001011b ; PPI A/B/C Mode 0, A Output, sonst Input
out ppi_ctl, al
jmp short $+2 ; I/O-Delay
mov al, 0 ; LED's aus (high aktiv)
out ppi_a, al
; PIC-Init.
mov al, 00010011b ; ICW1, ICW4 benoetigt, Bit 2 egal,
; Flankentriggerung
out icw_1, al
jmp short $+2 ; I/O-Delay
mov al, 00001000b ; ICW2, auf INT 8 gemapped
out icw_2_4, al
jmp short $+2 ; I/O-Delay
mov al, 00010001b ; ICW4, MCS-86, EOI, non-buffered,
; fully nested
out icw_2_4, al
jmp short $+2 ; I/O-Delay
mov al, 11111110b ; Kanal 0 am PIC demaskieren
; PIT K1
out ocw_1, al
; Interrupttabelle init.
mov word [intab0], isr_servotimer ; Interrupttabelle (Timer K1)
; initialisieren (Offset)
mov [intab0 + 2], cs ; (Segmentadresse)
sti ; ab jetzt Interrupts
ret
isr_servotimer: ; Timer fuer Servo, besser exklusiv (CLI)
push ax
; ...
; ...
; ...
isr_servotimer_out:
mov al, eoi ; EOI an PIC
out ocw_2_3, al
pop ax
iret

67
general/a4_sanduhr.asm Normal file
View File

@ -0,0 +1,67 @@
org 100h
cpu 8086
jmp start
; Variablen
hsec db 0 ; Hundertstel
; Konstanten
tc equ 18432 ; Zeitkonstante (1,8432 MHz Takt)
intab equ 20h ; Adresse Interrupttabelle PIT, K1
eoi equ 20h ; End Of Interrupt (EOI)
clrscr equ 0 ; Clear Screen
ascii equ 1 ; Funktion ASCII-Zeichenausgabe
hexbyte equ 4 ; HEX-Byte Ausgabe
conin equ 5 ; Console IN
conout equ 6 ; Console OUT
pitc equ 0a6h ; Steuerkanal PIT (Intervaltimer)
pit1 equ 0a2h ; Kanal 1 PIT
pic23 equ 0c0h ; PIC (Interruptcontroller), OCW2,3
pic1 equ 0c2h ; PIC (Interruptcontroller), OCW1
start:
; Initialisierungen (Display, Sanduhr stellen etc.) erfolgen hier
; ........
; ........
call tinit ; Initialisierung PIT 8253 (Kanal 1)
; und Interruptsystem
; Hintergrundprogramm
again:
; Der hier einzufügende Programmcode wird immer dann ausgeführt, wenn
; die Interruptserviceroutine nicht läuft (Hintergrundprogramm).
; Das wäre z.B. die Abfrage der Tastatur und die Manipulation der Statusbits.
jmp again
tinit: cli ; Interrupts aus
mov al, 01110110b ; Kanal 1, Mode 3, 16-Bit ZK
out pitc, al ; Steuerkanal
mov al, tc & 0ffh ; Low-Teil Zeitkonstante
out pit1, al
mov al, tc >> 8 ; High-Teil Zeitkonstante
out pit1, al
mov al, 11111110b ; Kanal 0 am PIC demaskieren
out pic1, al
mov word [intab], isr ; Interrupttabelle initialisieren
mov [intab + 2], cs
sti ; ab jetzt Interrupts
ret
isr: push ax
; Interruptservice:
; Hier ist z.B. der Programmcode einzufügen, der für die Zeitzählung und
; Anzeige zuständig ist. Der gemeinsame Ausgang aus der ISR ist "isr1".
isr1: mov al, eoi ; EOI an PIC
out pic23, al ; OCW
pop ax
iret

69
general/a4_stoppuhr.asm Normal file
View File

@ -0,0 +1,69 @@
org 100h
cpu 8086
jmp start
; Variablen
divider db 0
; Konstanten
tc equ 18432 ; Zeitkonstante (1,8432 MHz Takt)
intab equ 20h ; Adresse Interrupttabelle PIT, K1
eoi equ 20h ; End Of Interrupt (EOI)
clrscr equ 0 ; Clear Screen
ascii equ 1 ; Funktion ASCII-Zeichenausgabe
hexbyte equ 4 ; HEX-Byte Ausgabe
conin equ 5 ; Console IN
conout equ 6 ; Console OUT
pitc equ 0a6h ; Steuerkanal PIT (Intervaltimer)
pit1 equ 0a2h ; Kanal 1 PIT
pic23 equ 0c0h ; PIC (Interruptcontroller), OCW2,3
pic1 equ 0c2h ; PIC (Interruptcontroller), OCW1
start:
; Initialisierungen (Display, Uhr stellen etc.) erfolgen hier
; ........
; ........
call tinit ; Initialisierung PIT 8253 (Kanal 1)
; und Interruptsystem
; Hintergrundprogramm
again:
; Der hier einzufügende Programmcode wird immer dann ausgeführt, wenn
; die Interruptserviceroutine nicht läuft (Hintergrundprogramm).
; Das wäre z.B. die Abfrage der Tastatur und die Manipulation der Statusbits.
jmp again
tinit: cli ; Interrupts aus
mov al, 01110110b ; Kanal 1, Mode 3, 16-Bit ZK
out pitc, al ; Steuerkanal
mov al, tc & 0ffh ; Low-Teil Zeitkonstante
out pit1, al
mov al, tc >> 8 ; High-Teil Zeitkonstante
out pit1, al
mov al, 11111110b ; Kanal 0 am PIC demaskieren
out pic1, al
mov word [intab], isr ; Interrupttabelle initialisieren
mov [intab + 2], cs
sti ; ab jetzt Interrupts
ret
isr: push ax
inc byte [divider] ; Vorteiler durch 100
cmp byte [divider], 100 ; fertig?
jne isr1
mov byte [divider], 0 ; von vorne
; Hier ist z.B. der Programmcode einzufügen, der für die Zeitzählung und
; Anzeige zuständig ist. Der gemeinsame Ausgang aus der ISR ist "isr1".
isr1: mov al, eoi ; EOI an PIC
out pic23, al ; OCW
pop ax
iret