Das eBook Angewandte Mikroelektronik wurde von Hans Lohninger zur Unterstützung verschiedener Lehrveranstaltungen geschrieben. Weitere Informationen finden sie hier.


Betriebsprogramm zum Minimalsystem uP1


;
;********************************************************
;*                                                      *
;*    MINIMON                                           *
;*  Betriebsprogramm zum Minimalsystem uP1              *
;*                                                      *
;*  (C) H.Lohninger      März 1990                      *
;*                                                      *
;********************************************************
;
.SPACES ON
.FILLCHAR 0
.MACLIST OFF
;
;===================================================
;------- MACRO-Definitionen ------------------------
;===================================================
;
;
;----- AKKU zu HL addieren -------------------------
;
ADDHLA      .MACRO
            ADD     A,L
            LD      L,A
            LD      A,0
            ADC     A,H
            LD      H,A
            .ENDM
;
;----- if Byte-Variable TRUE -----------------------
;
IFTRUE      .MACRO  X,Y
            LD      A,(X)
            CP      TRUE
            JP      Z,Y
            .ENDM
;
;----- if Byte-Variable FALSE ----------------------
;
IFFALSE .MACRO      X,Y
            LD      A,(X)
            CP      FALSE
            JP      Z,Y
            .ENDM
;
;----- if AKKU = X,  then GOTO Y -------------------
;
IFA.EQ. .MACRO      X,Y
            CP      X
            JP      Z,Y
            .ENDM
;
;----- if AKKU <> X then GOTO Y -------------------
;
IFA.NE. .MACRO      X,Y
            CP      X
            JP      NZ,Y
            .ENDM
;
;----- Speichervariable laden ----------------------
;
LOAD        .MACRO X,Y
            LD      A,Y
            LD      (X),A
            .ENDM
;
;===================================================
;----- externe Labels ------------------------------
;===================================================
;
;------ EXTERNALS: Ports ---------------------------
;
            EXTERNAL PIN, POUT, DIPSW, ADCHI, ADCLO, DAC1HI, DAC1LO
            EXTERNAL CTC0, CTC1, CTC2, CTC3, DAC2HI, DAC2LO, MUXBAS
            EXTERNAL PIOAC, PIOAD, PIOBC, PIOBD, DSPDPM, DSPLAT
            EXTERNAL DARTAC, DARTAD, DARTBC, DARTBD
;
;------ EXTERNALS: VARIABLES -----------------------
;
            EXTERNAL STACK, CNTRLA, CNTRLB, STPOTA, STPOTB
            EXTERNAL VAWRBF, VBWRBF, VARDBF, VBRDBF
            EXTERNAL TRUE, FALSE, USOTLA, USOTLB
;
            ORG     0000H
;
;===================================================
            JP      COLD        ; Kaltstart
;===================================================
;
            .INCLUDE EXSIN2.ASM
;
;===================================================
;----- I N T E R R U P T - H A N D L E R -----------
;===================================================
;
            ORG     00100H
;
ICTC:       DEFW    IFREQ       ; CTC0
            DEFW    IGNORE      ; CTC1
            DEFW    IGNORE      ; CTC2
            DEFW    ICLOCK      ; CTC3
            DEFS    8
;
IDART:      DEFW    PUTICB      ;DARTB: Sender leer
            DEFW    ITBRKB      ;DARTB: Statuswechsel
            DEFW    GETICB      ;DARTB: Empfänger voll
            DEFW    INTERB      ;DARTB: spezielle Ausnahme
            DEFW    PUTICA      ;DARTA: Sender leer
            DEFW    ITBRKA      ;DARTA: Statuswechsel
            DEFW    GETICA      ;DARTA: Empfänger voll
            DEFW    INTERA      ;DARTA: spezielle Ausnahme
;
IPIOA:      DEFW    IGNORE      ; PIO A
IPIOB:      DEFW    IGNORE      ; PIO B
;
;===================================================
;------ INTERRUPT: DART-A break --------------------
;===================================================
;
ITBRKA:     PUSH    AF
            LD      A,10H
            OUT     (DARTAC),A
            POP     AF
            EI
            RETI
;
;===================================================
;------ INTERRUPT: DART-B break --------------------
;===================================================
;
ITBRKB:     PUSH    AF
            LD      A,10H
            OUT     (DARTBC),A
            POP     AF
            EI
            RETI
;
;===================================================
;------ INTERRUPT: DART-A Fehler -------------------
;===================================================
;
INTERA:     PUSH    AF
            LD      A,30H
            OUT     (DARTAC),A
            POP     AF
            EI
            RETI
;
;===================================================
;------ INTERRUPT: DART-B Fehler -------------------
;===================================================
;
INTERB:     PUSH    AF
            LD      A,30H
            OUT     (DARTBC),A
            POP     AF
            EI
            RETI
;
;===================================================
;---- nicht initialisierte Interrupts ignorieren ---
;===================================================
;
IGNORE:     EI
            RETI
;
            .INCLUDE IDARTA.ASM
;
;===================================================
;------ INTERRUPT: Empfänger DART-B voll -----------
;===================================================
;
            .GLOBAL GETICB
GETICB:     PUSH    AF
            PUSH    HL
            PUSH    DE
            PUSH    BC
            IN      A,(DARTBD)  ;Zeichen von DART lesen
;
$5:         LD      HL,CNTRLB
            DEC     (HL)        ;Verarbeitung der
            INC     (HL)        ;  Control-Codes ein ?
            JR      Z,$2
;
            IFA.NE. 'S'-40H,$3  ;^S ?
            LD      HL,STPOTB
            LD      (HL),TRUE   ;Ausgabe stoppen
            JR      $1
;
$3:         IFA.NE. 'Q'-40H,$6  ;^Q ?
            LD      HL,STPOTB
            LD      (HL),FALSE  ;Ausgabe fortsetzen
            CALL    TRMDTB
            JR      $1
;
$6:         IFA.EQ. 'C'-40H,$4  ;^C ?
;
$2:         LD      HL,VBRDBF   ;Zeichen in FIFO schreiben
            CALL    WRFIFO
            LD      HL,VBRDBF   ;RTS rücksetzen ?
            CALL    TSTFIF
            CP      0FAH        ;mehr als 250 Zeichen ?
            JR      C,$1
            LD      A,5
            OUT     (DARTBC),A
            LD      A,(DBREG5)
            RES     1,A
            LD      (DBREG5),A
            OUT     (DARTBC),A  ;RTS rücksetzen
$1:         POP     BC
            POP     DE
            POP     HL
            POP     AF
            EI
            RETI
;
$4:         LD      HL,WARM     ;Warmstart
            PUSH    HL
            LD      HL,STPOTB   ;Ausgabe einschalten
            LD      (HL),FALSE
            EI
            RETI
;
            .INCLUDE ICLOCK.ASM
;
;===================================================
;--- Zeichen von DART B lesen ----------------------
;===================================================
;
;Eingang:   -
;Ausgang:   CF = 1, falls kein Zeichen vorhanden
;                       CF = 0, AKKU enthält gültiges Zeichen
;
            .GLOBAL RDV24B
RDV24B:     PUSH    HL
            PUSH    BC
            LD      HL,VBRDBF   ;RTS setzen ?
            CALL    TSTFIF
            CP      100         ;weniger als 100 Zeichen ?
            JR      NC,$1
            LD      A,5
            OUT     (DARTBC),A
            LD      A,(DBREG5)
            SET     1,A
            LD      (DBREG5),A
            OUT     (DARTBC),A  ;RTS setzen
$1:         LD      HL,VBRDBF
            CALL    RDFIFO
            POP     BC
            POP     HL
            RET
;
            .INCLUDE SETPDA.ASM
;
;===================================================
;--- Protokoll von DART-B einstellen ---------------
;===================================================
;
;Eingang:   AKKU enthält Steuerzeichen
;Ausgang:   Protokoll von DART-A eingestellt
;
;           8,7,6 ... Baudrate:
;                       OFF OFF OFF = 150 Baud
;                       OFF OFF ON  = 300 Baud
;                       OFF ON  OFF = 600 Baud
;                       OFF ON  ON  = 1200 Baud
;                       ON  OFF OFF = 2400 Baud
;                       ON  OFF ON  = 4800 Baud
;                       ON  ON  OFF = 9600 Baud
;                       ON  ON  ON  = 19200 Baud
;           5 ..... Zahl der Datenbits:
;                       OFF = 7 Datenbits
;                       ON  = 8 Datenbits
;           4 ..... Parität:
;                       ON  = Paritybit wird erzeugt
;                       OFF = Paritybit wird nicht erzeugt
;           3 ..... Parity:
;                       OFF = even
;                       ON  = odd
;           2 ..... Zahl der Stoppbits
;                       ON  = 2 Stoppbits
;                       OFF = 1 Stoppbit
;           1 ..... unbenutzt
;
            .GLOBAL SETPDB
SETPDB:     PUSH    AF
            PUSH    HL
            LD      (PROTBK),A
            SRL     A           ;Baudrate
            SRL     A
            SRL     A
            SRL     A
            AND     0EH
            PUSH    AF          ;speichern für CLK-mode
            LD      HL,BAUDTB
            ADDHLA
;           LD      A,3
;           OUT     (CTC1),A    ;Timer anhalten
            LD      A,(HL)
            OUT     (CTC1),A    ;Mode-Word laden
            INC     HL
            LD      A,(HL)
            OUT     (CTC1),A    ;Zeitkonstante laden
;
            LD      HL,PROTBK   ;Parität
            POP     AF
            CP      4           ;Baudrate <= 300 ?
            LD      A,044H      ;x16 Modus
            JR      NC,$6
            LD      A,0C4H      ;x64 Modus
$6:         BIT     2,(HL)      ;Parität even/odd
            JR      NZ,$1
            SET     1,A
$1:         BIT     3,(HL)      ;Parität ein/aus
            JR      Z,$2
            SET     0,A
$2:         BIT     1,(HL)      ;Stoppbits
            JR      Z,$5
            SET     3,A
$5:         PUSH    AF          ;DART laden
            LD      A,4
            OUT     (DARTBC),A
            POP     AF
            OUT     (DARTBC),A
;
            LD      A,5         ;Zahl der Sender Datenbits
            OUT     (DARTBC),A
            LD      A,0AAH
            BIT     4,(HL)
            JR      Z,$3
            SET     6,A
$3:         OUT     (DARTBC),A
            LD      (DBREG5),A  ;Backup Register 5
;
            LD      A,3         ;Empfänger Datenbits
            OUT     (DARTBC),A
            LD      A,041H
            BIT     4,(HL)
            JR      Z,$4
            SET     7,A
$4:         OUT     (DARTBC),A
;
            POP     HL
            POP     AF
            RET
;
            .DATA
DBREG5:     DEFB    0           ;Backup Register 5
            .CODE
;
;===================================================
;--- DART-A & DART-B nach DIP-Swicthes einstellen --
;===================================================
;
; Zur Funktion der Schalter siehe Routine SETPDA
;
;
            .GLOBAL SETDSW
SETDSW:     IN      A,(DIPSW)
            CALL    SETPDA      ;Protokoll DART-A
            CALL    SETPDB      ;Protokoll DART-B
            RET
;
            .INCLUDE ODARTA.ASM
;
;===================================================
;------ INTERRUPT: Zeichen auf DART-B senden -------
;===================================================
;
PUTICB: CALL            TRMDTB      ;ein Zeichen übertragen
            EI
            RETI
;
            .GLOBAL TRMDTB
TRMDTB:     PUSH    AF
            PUSH    HL
            IFTRUE  STPOTB,$1   ;^S ?
            LD      HL,VBWRBF
            CALL    RDFIFO
            JR      C,$2
            OUT     (DARTBD),A  ;Zeichen ausgeben
$1:         POP     HL
            POP     AF
            RET
;
$2:         LOAD    USOTLB,TRUE
            LD      A,1         ;Interrupt abschalten
            OUT     (DARTBC),A
            LD      A,(DTBWR1)
            RES     1,A
            LD      (DTBWR1),A
            OUT     (DARTBC),A
            JR      $1
;
            .DATA
DTBWR1: DEFB        0
            .CODE
;
;===================================================
;---- Ausgabe eines Zeichens auf DART-B ------------
;===================================================
;
;Eingang:   Daten im AKKU
;Ausgang:   Zeichen wird im Spoolerpuffer abgelegt
;
            .GLOBAL WRV24B
WRV24B:     PUSH    AF
            PUSH    HL
            PUSH    DE
$1:         LD      HL,VBWRBF   ;Spooler voll ?
            DI
            CALL    WRFIFO      ;Zeichen in Spooler
            EI
            JR      C,$1        ;FIFO voll, warten
            DI
            IFFALSE USOTLB,$2       ;Spooler leer ?
            LOAD    USOTLB,FALSE            ;Spoolerflag rücksetzen
            LD      A,1
            OUT     (DARTBC),A
            LD      A,(DTBWR1)
            SET     1,A
            LD      (DTBWR1),A
            OUT     (DARTBC),A
            CALL    TRMDTB      ;erstes Zeichen übertragen
$2:         EI
            POP     DE
            POP     HL
            POP     AF
            RET
;
;===================================================
;------ hexadezimale Ausgabe HL-Inhalt -------------
;===================================================
;
;Eingang:   HL enthält 16-Bit-Wert
;Ausgang:   Wert hexadezimal auf DART-A ausgegeben
;
OUTHXH:     LD      A,H
            CALL    OUTHXA
            LD      A,L
            CALL    OUTHXA
            RET
;
;===================================================
;------ hexadezimale Ausgabe AKKU-Inhalt -----------
;===================================================
;
;Eingang:   AKKU enthält Wert
;Ausgang:   Wert hexadezimal auf DART-A ausgegeben
;
            .GLOBAL OUTHXA
OUTHXA:     PUSH    AF
            RRA
            RRA
            RRA
            RRA
            CALL    OUTNIB      ;erstes Nibble
            POP     AF
            CALL    OUTNIB      ;zweites Nibble
            RET
;
;===================================================
;--- hexadezimale Ausgabe low nibble Register A ----
;===================================================
;
;Eingang:   AKKU enthält nibble (Bit 0..3)
;Ausgang:   hexadezimale Ausgabe auf DART-A
;
            .GLOBAL OUTNIB
OUTNIB:     AND     0FH         ;4 Bits verwenden
            ADD     A,90H
            DAA                 ;DAA-Trick
            ADC     A,40H
            DAA
            CALL    WRV24A
            RET
;
;===================================================
;---- Ausgabe eines Wertes auf DAC2 ----------------
;===================================================
;
;Eingang:   16-Bit-Wert in HL
;Ausgang:   vordersten 12 Bit werden an DAC2 ausgegeben
;
            .GLOBAL ODAC2
ODAC2:      PUSH    AF          ;Resgister AF sichern
            LD      A,L
            OUT     (DAC2LO),A  ;niederwertiges Byte ausgeben
            LD      A,H
            OUT     (DAC2HI),A  ;höherwertiges Byte ausgeben
            POP     AF
            RET
;
;===================================================
;------ 7-Segment Anzeige testen -------------------
;===================================================
;
;Eingang:   -
;Ausgang:   Display-Test, zuerst alle Dezimalpunkte und
;                       Minuszeichen, dann sukzessive alle Ziffern
;                       durchs Display schieben.
;
            .GLOBAL TSTDSP
TSTDSP:     CALL    CLRDSP
            LD      A,0FFH      ;alle Dezimalpunkte und
            OUT     (DSPDPM),A  ;  Minuszeichen aktivieren
            LD      HL,0FFFFH   ;400 ms warten
            CALL    DELAY
            CALL    CLRDSP      ;Anzeige löschen
            LD      A,9
            LD      (TSTDSD),A  ;sukzessive Ziffernreihe
TSTDS2:     LD      A,(TSTDSD)  ;  durchschieben
            INC     A
            LD      (TSTDSD),A
            LD      B,6
TSTDS1:     LD      C,B         ;sechs Ziffern anzeigen
            DEC     C
            CALL    DIGDSP
            INC     A
            DJNZ    TSTDS1
            LD      HL,3000H    ;warten bis zum nächsten
            CALL    DELAY       ;  Durchgang
            LD      A,(TSTDSD)
            AND     0FH
            CP      9
            JR      NZ,TSTDS2
            CALL    CLRDSP
            RET
;
            .DATA
TSTDSD:     DEFB    0           ;erste Ziffer der Testanzeige
            .CODE
;
;===================================================
;------ Einzelne Ziffer anzeigen -------------------
;===================================================
;
;Eingang:   AKKU = Ziffer zur Anzeige (0-9)
;                       C = Adresse der Ziffer (0-5,
;                       0 = letzte Ziffer, 5 = vorderste Ziffer)
;Ausgang:   Anzeige der Ziffer
;
            .GLOBAL DIGDSP
DIGDSP:     PUSH    AF
            PUSH    BC
            AND     0FH         ;Ziffer
            SLA     C           ;Stelle einbauen
            SLA     C
            SLA     C
            SLA     C
            SLA     C
            OR      C
            OUT     (DSPLAT),A  ;Ziffer ausgeben
            POP     BC
            POP     AF
            RET
;
;===================================================
;------ Ziffernanzeige löschen ---------------------
;===================================================
;
;Eingang:   -
;Ausgang:   Ziffernanzeige gelöscht
;
            .GLOBAL CLRDSP
CLRDSP:     PUSH    AF
            PUSH    BC
            LD      A,0
            LD      (DSPDPS),A  ;Dezimalpunkte und
            OUT     (DSPDPM),A  ;  Minuszeichen löschen
            LD      B,6
CLRDS1:     LD      A,B         ;alle Ziffern löschen
            DEC     A
            RRCA
            RRCA
            RRCA
            OR      0FH
            OUT     (DSPLAT),A
            DJNZ    CLRDS1
            POP     BC
            POP     AF
            RET
;
            .DATA
DSPDPS:     DEFB    0           ;Status Dezimalpunkte
            .CODE
;
;===================================================
;-- Ausgabe einer dezimalen Zahl am 7-Segmentdisplay
;===================================================
;
;Eingang:   HL = Zahl zur Ausgabe
;Ausgang:   Zahl wird dezimal rechts ausgerichtet ausgegeben,
;                       führende Nullen werden nicht unterdrückt
;                       max. darstellbarer Bereich: -32768 ... +32767
;
            .GLOBAL DSPHL
DSPHL:      PUSH    AF
            PUSH    BC
            PUSH    DE
            PUSH    HL
            CALL    CLRDSP      ;Anzeige löschen
            LD      B,5         ;fünf Ziffern
            LD      C,0
$1:         CALL    DIV10       ;HL = HL/10
            CALL    DIGDSP      ;Rest ausgeben
            INC     C
            DJNZ    $1
            POP     HL
            PUSH    HL
            LD      C,1         ;Vorzeichen überprüfen
            CALL    RESMIN
            BIT     7,H         ; negativ ?
            JR      Z,$2
            LD      C,1
            CALL    SETMIN      ;ja, minus setzen (MSD)
$2:         POP     HL
            POP     DE
            POP     BC
            POP     AF
            RET
;
;===================================================
;------- Division durch 10 (mit Vorzeichen) --------
;===================================================
;
;Eingang:   HL = Zahl mit Vorzeichen (2er Komplement)
;Ausgang:   HL = Quotient (2er Komplement)
;           A = Rest (Absolut !!)
;
            .GLOBAL DIV10
DIV10:      PUSH    BC
            LD      A,TRUE
            LD      (VZFLAG),A
            BIT     7,H         ;Vorzeichen testen
            JR      Z,$3
            LD      A,FALSE
            LD      (VZFLAG),A
            LD      DE,0
            EX      DE,HL
            OR      A
            SBC     HL,DE
$3:         LD      B,12        ;Divisionsroutine
$1:         LD      A,H
            SUB     50H
            CCF
            JR      NC,$2
            LD      H,A
$2:         RL      L
            RL      H
            DJNZ    $1
            LD      B,H         ;Rest in AKKU
            LD      A,H
            AND     0FH
            LD      H,A
            LD      A,B
            SRL     A
            SRL     A
            SRL     A
            SRL     A
            PUSH    AF
            IFTRUE  VZFLAG,$4   ;negative Zahl ?
            LD      DE,0
            EX      DE,HL
            OR      A
            SBC     HL,DE
$4:         POP     AF
            POP     BC
            RET
;
            .DATA
VZFLAG:     DEFB    0           ;Vorzeichen
            .CODE
;
;===================================================
;----- Dezimalpunkt setzen -------------------------
;===================================================
;
;Eingang:   C holds digit number (0..5)
;Ausgang:   DP is illuminated
;
            .GLOBAL SETDP
SETDP:      PUSH    BC
            PUSH    AF
            LD      A,C
            CP      6
            JR      NC,$1
            LD      B,C
            INC     B
            INC     B
            LD      A,1         ;adjust for error PCB
            XOR     B
            LD      B,A
            LD      A,1
$2:         ADD     A,A         ;calc. DP
            DJNZ    $2
            LD      B,A
            LD      A,(DSPDPS)
            AND     3
            OR      B
            LD      (DSPDPS),A  ;backup new DP
            OUT     (DSPDPM),A  ;output data
$1:         POP     AF
            POP     BC
            RET
;
;===================================================
;------ Minuszeichen setzen ------------------------
;===================================================
;
;Eingang:   C = Adresse des Minuszeichens (1..MSD, 0..MSD-1)
;Ausgang:   Minuszeichen gesetzt
;
            .GLOBAL SETMIN
SETMIN:     LD      A,C
            CP      0
            JR      Z,SETMI1
            CP      1
            RET     NZ
            LD      A,(DSPDPS)
            SET     1,A
SETMI2:     LD      (DSPDPS),A
            OUT     (DSPDPM),A
            RET
SETMI1:     LD      A,(DSPDPS)
            SET     0,A
            JR      SETMI2
;
;===================================================
;----- Minuszeichen rücksetzen ---------------------
;===================================================
;
;Eingang:   C = Adresse des Minuszeichens (1..MSD, 0..MSD-1)
;Ausgang:   Minuszeichen zurückgesetzt
;
            .GLOBAL RESMIN
RESMIN:     LD      A,C
            CP      0
            JR      Z,RESMI1
            CP      1
            RET     NZ
            LD      A,(DSPDPS)
            RES     1,A
RESMI2:     LD      (DSPDPS),A
            OUT     (DSPDPM),A
            RET
RESMI1:     LD      A,(DSPDPS)
            RES     0,A
            JR      RESMI2
;
            .INCLUDE FIFO.ASM
;
;===================================================
;------ Kaltstart ----------------------------------
;===================================================
;
PORTTB:     DEFB    < ICTC, CTC0            ;Interruptvektor, low byte
            DEFB    005H,CTC2   ;Baudrate 9600, DART-A
            DEFB    00CH,CTC2
            DEFB    005H,CTC1   ;Baudrate 9600, DART-B
            DEFB    00CH,CTC1
            DEFB    005H,CTC3   ;Timer, 1 ms
            DEFB    250,CTC3
;
            DEFB    02H,DARTBC
            DEFB    < IDART,DARTBC          ;Interruptvektor, low byte
            DEFB    001H,DARTBC
            DEFB    0FCH,DARTBC ;Status berücksichtigen
            DEFB    003H,DARTBC ;auto enable aus
            DEFB    0C1H,DARTBC ;Empfänger 8 Bits
            DEFB    004H,DARTBC ;X16 mode, 2 stop, no parity
            DEFB    044H,DARTBC
            DEFB    005H,DARTBC ;DTR-Control
            DEFB    0E8H,DARTBC ;Sender 8 Bits
;
            DEFB    003H,DARTAC ;Empfänger 8 Bits, auto enable aus
            DEFB    0C1H,DARTAC
            DEFB    005H,DARTAC ;Sender 8 Bits, DTR low
            DEFB    0E8H,DARTAC
            DEFB    004H,DARTAC ;X16 mode, 2 stop, no parity
            DEFB    044H,DARTAC
            DEFB    001H,DARTAC ;Interrupts einschalten
            DEFB    0FAH,DARTAC
;
            DEFB    < IPIOA,PIOAC           ;Interruptvektor
            DEFB    11001111B,PIOAC         ;Modus 3 (Bit I/O)
            DEFB    11111111B,PIOAC         ;nur Eingänge
            DEFB    00000111B,PIOBC         ;Interrupt aus
;
            DEFB    < IPIOB,PIOBC           ;Interruptvektor
            DEFB    11001111B,PIOBC         ;Modus 3 (Bit I/O)
            DEFB    11111111B,PIOBC         ;nur Eingänge
            DEFB    00000111B,PIOBC         ;Interrupt aus
;
            DEFB    000H,DAC1LO ;DAC 1
            DEFB    080H,DAC1HI
            DEFB    000H,DAC2LO ;DAC 2
            DEFB    080H,DAC2HI
            DEFB    000H,MUXBAS ;MUX, Kanal 0
;
            DEFB    0,0         ;ende der Tabelle
;
            .GLOBAL COLD
COLD:       LD      SP,STACK
            LD      HL,30000    ;Stabilisation abwarten
            CALL    DELAY
            LD      HL,PORTTB   ;Ports initialisieren
COLDNX: LD  B,(HL)  ;Daten
            INC     HL
            LD      C,(HL)      ;Port-Nummer
            INC     HL
            LD      A,B
            OR      C           ;Ende der Tabelle ?
            JR      Z,COLD1
            OUT     (C),B
            JR      COLDNX
;
COLD1:      LOAD    STPOTA,FALSE            ;Ausgang DART-A ein
            LOAD    STPOTB,FALSE            ;Ausgang DART-B ein
            LOAD    CNTRLA,TRUE ;Control-Zeichen ein
            LOAD    CNTRLB,TRUE ;Control-Zeichen ein
            LOAD    USOTLA,TRUE ;Spooler leer
            LOAD    USOTLB,TRUE ;Spooler leer
            LOAD    DTAWR1,0FAH ;Interrupt DARTA
            LOAD    DTBWR1,0FEH ;Interrupt DARTB
            LOAD    (DPBLNK),0  ;Dezimalpunkteblinker
            LD      HL,0
            LD      (CLKCNT),HL ;Uhr rücksetzen
            LD      HL,1
            LD      (SEK),HL    ;Sekundenzähler
            LOAD    FREQ,0      ;Frequenz
            LD      HL,VARDBF
            CALL    CLRFIF      ;Eingangspuffer löschen
            LD      HL,VBRDBF
            CALL    CLRFIF      ;Eingangspuffer löschen
            LD      HL,VAWRBF   ;Ausgangspuffer löschen
            CALL    CLRFIF
            LD      HL,VBWRBF   ;Ausgangspuffer löschen
            CALL    CLRFIF
;
            LD      HL,ICTC     ;Interruptstruktur einrichten
            LD      A,L
            AND     1FH
            JR      Z,CLDIOK    ;Adresse OK
            HALT
;
CLDIOK: LD  A,H
            LD      I,A         ;Interruptvektor, high Byte
            IM      2           ;Z80 - Modus (IM 2)
            EI
            CALL    SETDSW      ;Protokoll einstellen
            CALL    TSTDSP      ;7-segment Anzeige testen
;
;===================================================
;------ Warmstart ----------------------------------
;===================================================
;
WARM:       LD      SP,STACK
            IN      A,(DIPSW)   ;Experiment-Nummer abfragen
            LD      L,A
            LD      H,0
            ADD     HL,HL       ;Wortadressierung
            PUSH    HL
            LD      DE,ENDTAB-EXPTAB ;überprüfen, ob DIP-Switch
            OR      A           ;  nicht auf zu hohen Wert
            SBC     HL,DE       ;  eingestellt ist
            POP     HL
            JR      C,$1
            LD      A,(DPBLNK)  ;alle Dezimalpunkte
            XOR     A,FCH       ;  aktivieren
            LD      (DPBLNK),A
            OUT     (DSPDPM),A
            LD      HL,0FFFFH   ;700 ms warten
            CALL    DELAY
            JR      WARM        ;bis DIP-Switch ok
$1:         CALL    CLRDSP
            LD      DE,EXPTAB   ;Tabelleneintrag mit Startadresse
            ADD     HL,DE       ;ermitteln
            LD      A,(HL)
            INC     HL
            LD      H,(HL)
            LD      L,A
            JP      (HL)        ;Routine starten
;
            .DATA
DPBLNK:     DEFB    0           ;Dezimalpunkte blinken
            .CODE
;
EXPTAB:     DEFW    INVERT      ;0 = Inverter
            DEFW    RAMTST      ;1 = RAM-Test
            DEFW    LAUFL       ;2 = Lauflicht
            DEFW    EXPCNT      ;3 = Zähler
            DEFW    EXGATE      ;4 = Gatteremulation
            DEFW    STPCLK      ;5 = Stoppuhr
            DEFW    FQCNT       ;6 = Frequenzzähler
            DEFW    PIOKEY      ;7 = Tastaturscan
            DEFW    CENTRX      ;8 = Centronics Schnittstelle
            DEFW    BYTSND      ;9 = Zeichen auf DART senden
            DEFW    BYTREC      ;10 = Zeichen auf DART empfangen
            DEFW    PROTOC      ;11 = Protokoll-Umsetzung
            DEFW    DVM         ;12 = Digitalvoltmeter
            DEFW    SINUSA      ;13 = Sinusgenerator Version A
            DEFW    SINUSB      ;14 = Sinusgenerator Version B
            DEFW    LFLSIN      ;15 = Lauflicht & Sinusgenerator
            DEFW    FNCGEN      ;16 = Funktionsgenerator
ENDTAB:     EQU     $           ;Ende der Tabelle
;
DUMMYP:     JP      WARM
;
;===================================================
;------ 32-Bit-Multiplikation (mit Vorzeichen) -----
;===================================================
;
;Eingang:   BC, DE = Argumente für 32-Bit-Multiplikation
;Ausgang:   DE-HL = BC * DE (signed)
;
            .GLOBAL MLT32S
MLT32S:     LD      A,D
            XOR     B
            PUSH    AF
            BIT     7,D         ;negativ ?
            JR      Z,$1
            LD      A,D
            CPL
            LD      D,A
            LD      A,E
            CPL
            LD      E,A
            INC     DE
$1:         BIT     7,B         ;BC negativ ?
            JR      Z,$2
            LD      A,B
            CPL
            LD      B,A
            LD      A,C
            CPL
            LD      C,A
            INC     BC
$2:         CALL    MLT32U      ;vorzeichenlos multiplizieren
            POP     AF
            BIT     7,A
            RET     Z
            CALL    CMPL32
            RET
;
;===================================================
;---- Zweierkomplement einer 32-Bit-Zahl -----------
;===================================================
;
;Eingang:   HL-DE = 32-Bit signed integer
;Ausgang:   HL-DE = 32-Bit negated integer (2er Komplement)
;
.GLOBAL CMPL32
CMPL32:     LD      A,H
            CPL
            LD      H,A
            LD      A,L
            CPL
            LD      L,A
            LD      A,D
            CPL
            LD      D,A
            LD      A,E
            CPL
            LD      E,A
            LD      A,1
            ADD     A,E
            LD      E,A
            LD      A,0
            ADC     A,D
            LD      D,A
            LD      A,0
            ADC     A,E
            LD      E,A
            LD      A,0
            ADC     A,L
            LD      L,A
            LD      A,0
            ADC     A,H
            LD      H,A
            RET
;
;===================================================
;----- 32-Bit-Multiplikation (ohne Vorzeichen) -----
;===================================================
;
;Eingang:   BC, DE = Argumente für 32-Bit-Multiplikation
;Ausgang:   DE-HL = BC * DE (vorzeichenlos)
;
            .GLOBAL MLT32U
MLT32U:     PUSH    AF          ;Register sichern
            PUSH    BC
            EX      AF,AF'
            PUSH    AF
            EX      AF,AF'
            LD      A,E
            CALL    MPYABC      ;untere Hälfte multiplizieren
            PUSH    HL
            EX      AF,AF'
            LD      A,D
            CALL    MPYAB2      ;obere Hälfte multiplizieren
            LD      D,A
            EX      AF,AF'
            ADD     A,H         ;Ergebnisse kombinieren
            LD      H,L
            LD      L,E
            LD      E,A
            JR      NC,$1
            INC     D
$1:         POP     BC
            ADD     HL,BC
            JR      NC,$2
            INC     DE
$2:         EX      AF,AF'      ;Register wiederherstellen
            POP     AF
            EX      AF,AF'
            POP     BC
            POP     AF
            RET
;
MPYABC:     LD      E,0         ;A-H-L = BC*A
MPYAB2:     LD      L,E         ;Multiplikation mit A durch
            LD      H,E         ;  Schieben von A und šber-
            ADD     A,A         ;  prüfung des Carry-Bits
            JR      NC,$1       ;schnelle Version ohne
            ADD     HL,BC       ;  Schleifen-Zähler
            ADC     A,E
$1:         ADD     HL,HL
            ADC     A,A
            JR      NC,$2
            ADD     HL,BC
            ADC     A,E
$2:         ADD     HL,HL
            ADC     A,A
            JR      NC,$3
            ADD     HL,BC
            ADC     A,E
$3:         ADD     HL,HL
            ADC     A,A
            JR      NC,$4
            ADD     HL,BC
            ADC     A,E
$4:         ADD     HL,HL
            ADC     A,A
            JR      NC,$5
            ADD     HL,BC
            ADC     A,E
$5:         ADD     HL,HL
            ADC     A,A
            JR      NC,$6
            ADD     HL,BC
            ADC     A,E
$6:         ADD     HL,HL
            ADC     A,A
            JR      NC,$7
            ADD     HL,BC
            ADC     A,E
$7:         ADD     HL,HL
            ADC     A,A
            RET     NC
            ADD     HL,BC
            ADC     A,E
            RET
;
;
;===================================================
;---- Include-Dateien für die Experimente ----------
;===================================================
;
;  Die folgenden Include-Dateien werden für die Experimente verwendet:
;
            .INCLUDE EXRAMTST.ASM
            .INCLUDE EXBYTREC.ASM
            .INCLUDE EXBYTSND.ASM
            .INCLUDE EXPPCNT.ASM
            .INCLUDE EXPLAUFL.ASM
            .INCLUDE EXPINV.ASM
            .INCLUDE EXPROTOC.ASM
            .INCLUDE EXSIN1.ASM
            .INCLUDE EXLFLSIN.ASM
            .INCLUDE EXFNCGEN.ASM
            .INCLUDE EXDVM.ASM
            .INCLUDE EXCLOCK.ASM
            .INCLUDE EXFREQ.ASM
            .INCLUDE EXPIOKEY.ASM
            .INCLUDE EXCENTRX.ASM
;
            .END


Last Update: 2008-05-31