P8000/firmware/TERMINAL/p8t.up.s

571 lines
11 KiB
ArmAsm

!*******************************************************
* *
* T E R M I N A L *
* *
* mit Einchip-Mikrorechner U 882 und CRTC 8275 *
* ============================================ *
* *
* UNTERPROG Module; Version 3.1: *
* - 24 Zeilen / 80 Zeichen *
* Inhalt: *
* - Unterprogramme fuer die anderen Module *
* *
********************************************************
Bearbeiter: Heller / WAT
Stand: 09.03.87
Disk: Heller.8 (Mini)
Name: P8T.UP !
UP MODULE
CONSTANT
! 'Z8T.VEREINBARUNGEN' !
$LISTOFF
! Werte !
P01EXT := %96 ! P0:=A8...A14, P1:=AD0...AD7, Stack intern !
P01TRI := %9E ! tri state: P0,P1,AS,DS,R/W !
! Bit Definitionen !
B0 := %1 ! bit 0 !
B1 := %2 ! bit 1 !
B2 := %4 ! bit 2 !
B3 := %8 ! bit 3 !
B4 := %10 ! bit 4 !
B5 := %20 ! bit 5 !
B6 := %40 ! bit 6 !
B7 := %80 ! bit 7 !
NB0 := %FE ! negiertes bit 0 !
NB1 := %FD ! negiertes bit 1 !
NB2 := %FB ! negiertes bit 2 !
NB3 := %F7 ! negiertes bit 3 !
NB4 := %EF ! negiertes bit 4 !
NB5 := %DF ! negiertes bit 5 !
NB6 := %BF ! negiertes bit 6 !
NB7 := %7F ! negiertes bit 7 !
! Bildparameter !
ZEILENZAHL := 24
ZEICHENZAHL := 80
! Adressen !
BRAM := %1000 ! Bildwiederholspeicher !
ZADR_TAB := %1780 ! Tabelle der Zeilenanfangsadr. !
CRT_PAR := %1C00 !Parameter lesen / schreiben !
CRT_COM := %1C01 ! Commands schreiben !
CRTL_STAT := %1C01 ! Status lesen !
ZG0 := %4000 ! ASCII-Zeichensatz !
ZG1 := %2000 ! Alternativ-Zeichensatz !
BELL_ADR := %8000 ! Akustischer Signalgeber !
! Display Commands !
RES_DISPL := %00
START_DISPL := %20
STOP_DISPL := %40
READ_LPEN := %60
LD_CURSOR := %80
ENABLE_INT := %A0
DISABLE_INT := %C0
PRES_COUNT := %E0
! Parameter fuer Display-Reset-Command !
RES1 := %4F ! 80 characters/row !
RES2 := %97 ! !
RES3 := %0B ! !
RES4 := %6C ! !
! Field Attribute Code !
FAC := %80 ! Field Attribute: Normal Mode !
FACH := %01 ! Highlight !
FACB := %02 ! Blink !
FACR := %10 ! Reverse video !
FACU := %20 ! Underline !
! ASCII Control Characters entsprechend ADM 31 !
NUL := %00 ! Null ^@ !
SOH := %01 ! Start of Heading ^A !
STX := %02 ! Start of Text ^B !
ETX := %03 ! End of Text ^C !
EOT := %04 ! End of Transmission ^D !
ENQ := %05 ! Inquiry (who are you) ^E !
ACK := %06 ! Acknewledge ^F !
BEL := %07 ! Bell ^G !
BS := %08 ! Backspace ^H !
HT := %09 ! Horizontal Tabulator ^I !
LF := %0A ! Line Feed ^J !
VT := %0B ! Vertical Tabulator ^K !
FF := %0C ! Forspace ^L !
CR := %0D ! Carriage Return ^M !
SO := %0E ! Shift out ^N !
SI := %0F ! Shift in ^O !
DLE := %10 ! Data Link Escape ^P !
DC1 := %11 ! Device Control ^Q !
DC2 := %12 ! ^R !
DC3 := %13 ! ^S !
DC4 := %14 ! ^T !
NAK := %15 ! Not Acknewl. ^U !
SYN := %16 ! Synchronous Idle ^V !
ETB := %17 ! End of Trans.-Block ^W !
CAN := %18 ! Cancel ^X !
EM := %19 ! End of Medium ^Y !
SBS := %1A ! Substitute ^Z !
ESC := %1B ! Escape Sequenz ^[ !
FS := %1C ! File Separator !
GS := %1D ! Group Separator ^] !
RS := %1E ! Cursor HOME ^^ !
US := %1F ! New Line ^~ !
$LISTON
$PAGE
EXTERNAL
ESC_SEQUENZ PROCEDURE
ESC_OUT_SEQ PROCEDURE
BREAK PROCEDURE
SIO_OUT PROCEDURE
P0, P1, P2, P3, STAT0, STAT1, STAT2 BYTE
SPALTZ, ZEILZ, CHAR BYTE
global
CLEAR_B LABEL
CLEAR_L label
ROLL_U2 label
ROLL_U3 label
$section SEC2 program
CHAR_ADRESSE PROCEDURE
!*******************************************************
*
* Berechnung der aktuellen Zeichenadresse
* Reg. Gruppe: 1
* Input: SPALTZ, ZEILZ, ZADR_TAB
* Output: RR12, akt. BRAM_ADR
*
*******************************************************!
ENTRY
ld r8,#HI ZADR_TAB
ld r9,#LO ZADR_TAB
add r9,ZEILZ ! Tabellenzeile, Ubertrag tritt nicht auf !
call READ_ADR ! codierte Adresse holen !
call ADR_DEC ! Adresse decodieren !
add r13,SPALTZ ! Spalte beruecksichtigen !
jr nc,CRA0 ! Uebertrag? !
inc r12
CRA0:
ret ! akt. BRAM_ADR in rr12 !
END CHAR_ADRESSE
ADR_DEC PROCEDURE
!*******************************************************
*
* Umwandlung 1byte -> 2byte Wert
* Input: r12, codierter Adresswert aus Tabelle
* Output: rr12, dekodierte BRAM_Zeilen_Adresse
*
*******************************************************!
ENTRY
ld r13,#%F0
and r13,r12
and r12,#%0F
or r12,#%10
ret
END ADR_DEC
READ_ADR PROCEDURE
!*******************************************************
*
* Lesen einer codierten Adresse aus ZADR_Tabelle (BRAM)
* Input: rr8, Tabellen-Adresse
* r12, Inhalt der Adresse
*
*******************************************************!
ENTRY
OR STAT0,#B1 ! MCU-Flag setzen !
RAWAIT:
TCM STAT0,#B0 ! DMA aktiv?, wenn ja, warten !
JR Z,RAWAIT
DI
lde r12,@rr8 ! lesen !
EI
AND STAT0,#NB1 ! MCU-Flag ruecksetzen !
RET
END READ_ADR
WR_ADR PROCEDURE
!*******************************************************
*
* Schreiben einer codierten Adresse in ZADR_Tabelle (BRAM)
* Input: rr10, Tabellen-Adresse
* r12, Inhalt der Adresse
*
*******************************************************!
ENTRY
OR STAT0,#B1 ! MCU-Flag setzen !
WAWAIT:
TCM STAT0,#B0 ! DMA aktiv?, wenn ja, warten !
JR Z,WAWAIT
DI
LDE @RR10,R12 ! schreiben !
EI
AND STAT0,#NB1 ! MCU-Flag ruecksetzen !
RET
END WR_ADR
WRITE_CHAR PROCEDURE
!*******************************************************
*
* Beschreiben des Bildram mit einem Zeichen
* Reg. Gruppe: 1
* Input: RR8 := Zieladresse
* R13 := Zeichen
*
*******************************************************!
ENTRY
OR STAT0,#B1 ! MCU-Flag setzen !
WRITECH0:
TCM STAT0,#B0 ! DMA aktiv?, wenn ja, warten !
JR Z,WRITECH0
DI
LDE @RR8,R13
EI
AND STAT0,#NB1 ! MCU-Flag ruecksetzen !
RET
END WRITE_CHAR
READ_CHAR PROCEDURE
!*******************************************************
*
* Ein Zeichen aus dem Bildram lesen
* Reg. Gruppe: 1
* Input: RR8 := Zieladresse
* Output: r12 := Zeichen
*
*******************************************************!
ENTRY
OR STAT0,#B1 ! MCU-Flag setzen !
READCH0:
TCM STAT0,#B0 ! DMA aktiv?, wenn ja, warten !
JR Z,READCH0
DI
lde r12,@rr8 ! Lesen !
EI
AND STAT0,#NB1 ! MCU-Flag ruecksetzen !
RET
END READ_CHAR
CURSOR_POS PROCEDURE
!*******************************************************
*
* Berechnung der neuen Cursor-Position
* Input: SPALTZ, ZEILZ
* Output: SPALTZ, ZEILZ (neue Werte)
*
*******************************************************!
ENTRY
INC SPALTZ
CP SPALTZ,#ZEICHENZAHL
JR NZ,CPOS0
CLR SPALTZ
INC ZEILZ
CP ZEILZ,#ZEILENZAHL
JR NZ,CPOS0
LD ZEILZ,#ZEILENZAHL-1 ! Cursor bleibt nach Rollen
in der letzen Zeile !
OR STAT0,#B2 ! Rollflag setzen !
CPOS0:
CALL LOAD_CURSOR
RET
END CURSOR_POS
LOAD_CURSOR PROCEDURE
!*******************************************************
*
* Laden der berechneten Cursor-Position in
* den CRTC
*
*******************************************************!
ENTRY
LD R8,#HI CRT_COM
LD R9,#LO CRT_COM
LD R10,#LD_CURSOR
LD R11,SPALTZ ! Spaltenposition 0...79 !
LD R12,ZEILZ ! Zeilenposition0...23 !
OR STAT0,#B1 ! MCU-Zugriff !
LCURSOR0:
TCM STAT0,#B0 ! DMA aktiv?, wenn ja warten !
JR Z,LCURSOR0
DI
LDE @RR8,R10 ! out command !
DECW RR8
LDE @RR8,R11 ! out char. pos in row !
LDE @RR8,R12 ! out row number !
EI
AND STAT0,#NB1 ! MCU-Zugriff beendet !
RET
END LOAD_CURSOR
ROLL PROCEDURE
!*******************************************************
*
* Umladen der Adressen-Tabelle im BRAM
* Input: rr8, Zeilenadr, init: ZADR_TAB
* r14, Zaehler, init: ZEILENZAHL-1
* Reg: rr8, rr9, r12, r13, r14
*
*******************************************************!
ENTRY
! init-Werte !
ld r8,#HI ZADR_TAB
ld r9,#LO ZADR_TAB
ld r14,#ZEILENZAHL-1 ! Zaehler !
ROLL_U2:
! 2. Eintrittspunkt: rr8 und r14 laden !
TM STAT0,#B2 ! Rollbit gesetzt? !
jr z,ROLL_U0
call CLEAR_LINE ! 1. Zeile loeschen vor Rollen !
ROLL_U3:
! 3. Eintrittspunkt: kein Zeilenloeschen, r14 laden !
ld r10,r8 ! Schreibadresse laden !
ld r11,r9
call READ_ADR ! 1. Tabellen-Wert holen !
ld r13,r12 ! 1. Wert ablegen !
ROLL_U1:
inc r9 ! naechste Adresse !
call READ_ADR
call WR_ADR ! Wert zurueckschreiben !
inc r11 ! Schreibadresse erhoehen !
djnz r14,ROLL_U1 ! !
ld r12,r13 ! 1. Wert rueckschreiben !
call WR_ADR
ROLL_U0:
AND STAT0,#NB2 ! Rollflag zuruecksetzen !
ret
END ROLL
ROLL_DOWN PROCEDURE
!*******************************************************
*
* Umladen der Adresentabelle im BRAM (vorwaerts)
* Input: rr8, Zeilenadr, init: ZADR_TAB+ZEILENZAHL
* r14, Zaehler, init ZEILENZAHL-1
* r15, ZEILZ, init 00
* Reg: rr8, rr9, r12, r13, r14, r15
*
*******************************************************!
ENTRY
! init-Werte !
ld r8,#HI ZADR_TAB
ld r9,#LO ZADR_TAB
ld r14,#ZEILENZAHL-1
add r9,r14 ! letzte Zeile !
sub r14,r15 ! Zaehler laden !
jr nz,ROLL_D2
call CLEAR_LINE ! nur loeschen, falls schon letzte Zeile !
jr ROLL_D0
ROLL_D2:
call CLEAR_LINE ! letzte Zeile loeschen !
ROLL_D3:
! Eintrittspunkt: kein Zeilenloeschen, r14 laden !
ld r10,r8 ! Schreibadresse laden !
ld r11,r9
call READ_ADR ! 1. Tabellenwert holen !
ld r13,r12 ! 1. Wert ablegen !
ROLL_D1:
dec r9 ! Lese-Adr. verringern !
call READ_ADR ! Lesen !
call WR_ADR ! Rueckschreiben !
dec r11 ! Schreibadresse verrringern !
djnz r14,ROLL_D1
ld r12,r13 ! 1. Wert zurueckschreiben !
call WR_ADR
ROLL_D0:
ret
END ROLL_DOWN
CLEAR_LINE PROCEDURE
!*******************************************************
*
* Loeschen einer Bildzeile
* Zeilenende: 'Reset to Standard Video'
* Input: RR8:=Anfangsadresse
* r11 = ZEICHENZAHL-1
* r15, Spalte fuer Beginn, init: 0
* Register: rr8, r10, r11, rr12, r15
*
*******************************************************!
ENTRY
ld r15,#%00 ! Initwert fuer Spalte !
CLEAR_L: ! 2. Eintrittspunkt: Parameter r15 !
and STAT2,#NB2
cl0:
push r8
push r9
call BRAM_ADR
jr cl1
! 3. Eintrittspunkt Loeschen vom Beginn bis Cursor !
CLEAR_B:
or STAT2,#B2
ld r15,#0
jr cl0
cl1:
jr z,ZLOESCH0
ld r13,#' ' ! Space !
ZLOESCH1:
call WRITE_CHAR ! Space schreiben !
incw rr8 ! naechste Adr !
djnz r11,ZLOESCH1
ZLOESCH0:
tm STAT2,#B2
jr z,ZLOESCH2
cp SPALTZ,#ZEICHENZAHL-1
jr nz,ZLOESCH3
ZLOESCH2:
LD R13,#FAC ! Reset to Standard Video !
call WRITE_CHAR
ZLOESCH3:
AND STAT0,#NB1 ! MCU-Zugriff beendet !
pop r9
pop r8
RET
END CLEAR_LINE
CLEAR_SCREEN PROCEDURE
!*******************************************************
*
* Loeschen des Bildschirms (24 Zeilen)
* am Ende jeder Zeile wird das Video-Attribut
* 'Reset to Standard Video' eingetragen
*
*******************************************************!
ENTRY
LD R8,#HI ZADR_TAB
LD R9,#LO ZADR_TAB
LD R6,#ZEILENZAHL ! Zaehler !
CLSC0:
CALL CLEAR_LINE
inc r9 ! naechste Zeile, kein Hi-Teil !
DJNZ R6,CLSC0
RET
END CLEAR_SCREEN
BRAM_ADR PROCEDURE
!*******************************************************
*
* Berechnung einer BRAM-ADR
* Input: rr8 = Zeilenanfangsadr., r15 = SPALTZ
* Output: rr12 = physische BRAM-ADR
* Z-Flag, wenn letzte Spalte
* Register: rr8, r11, rr12, r15
*
*******************************************************!
ENTRY
ld r11,#ZEICHENZAHL-1
call READ_ADR ! codierte BRAM-ADR !
call ADR_DEC ! physische BRAM-ADR !
ld r8,r12 ! Adr fuer WRITE_CHAR !
ld r9,r13
add r9,r15 ! Anfangsadr. !
jr nc,BRAM0
inc r8 ! Uebertrag? !
BRAM0:
tm STAT2,#B2
jr z,BRAM1 !Zeile loeschen zum Zeilenende!
!Zeile loeschen zum Cursor!
ld r11,SPALTZ
inc r11
ret
BRAM1:
sub r11,r15 ! Zaehler laden !
ret
END BRAM_ADR
END UP