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
|