.z80 ;================================================================ ;Erweiterte Zeichenausgaberoutine fuer Amstrad - CP/M plus ;und 8. Druckerbit ;Datei CPM3CHAR.MAC Version 29-Jan-89 ;(c) Helmut Tischer, Moosburg a.d. Isar ;Ausgabe erfolgt beschleunigt in durch VIDATT angegebener Darstellung. ;Deutsche Sonderzeichen werden schon im Original-Bios behandelt ; Bit 0 -> Durchgestrichen ; Bit 1 -> Invertiert ; Bit 2 -> gerastert (halbhell) ; Bit 3 -> Unterstrichen ; Bit 4 -> Tiefgestellt ; Bit 5 -> Hochgestellt ; Bit 6 -> Fettschrift ; Bit 7 -> Kursiv ;mit L80 /P:6C00,X10CHAR,X10CHAR/N/X/E nach 6C00h linken ; und resultierende X10CHAR.HEX ; dem nach 0C00h geladenem C10CPM3.EMS ueberlagern ;zur Aktivierung dieser Routine sind zusaetzliche Patches notwendig. ; Einige Patches gelten nur nachdem C10CPM3.EMS schon an die ; Dobbertin-Speichererweiterung angepasst wurde. ;C10CPM3.EMS nach 0C00h laden und folgendes einpatchen: ; 0C06 -> call 6C00h ;RamDisk-Initialisierung erweitern ; 0E5D -> ld de,8C58h ;neue Lage der Sektorpuffer ; 0E6E -> ld b,09h ;einen Daten-Sektorpuffer weniger ; 10FB -> ld hl,0AE58h ;Tabelle fuer ESC-Sequenzen mit Parameter ; 11A2 -> db 'u' ;Unterstreichen ausschalten ; dw 0AE8Ch ; db 'r' ;Unterstreichen einschalten ; dw 0AE84h ; db 'q' ;Invers ausschalten ; dw 0AE7Ch ; db 'p' ;Invers einschalten ; dw 0AE74h ; 1417 -> call 0AFB5h ;neues Screen-Reset ; 6C00 -> ***** Ergebnis dieses Assemblerlaufs eintragen ***** ; bei Aenderung von X10CHAR.MAC koennen sich Patch-Werte aendern! TXT_RESET equ 0BB51h SCR_RESET equ 0BC02h SCR_GET_MODE equ 0BC11h SCR_CLEAR equ 0BC14h MC_SEND_PRINTER equ 0BD31h TXT_WRITE_CHAR equ 0BDD3h SCR_MODE_CLEAR equ 0BDEBh MC_WAIT_PRINTER equ 0BDF1h ld hl,copyanf ;Ausgaberoutine an RunTime-Adresse kopieren ld de,0AE58h ld bc,copyend-copyanf ldir ld hl,outus ;Ausgaberoutine aktivieren ld (TXT_WRITE_CHAR+1),hl ld hl,scrmd ;Bildschirm loeschen abaendern ld (SCR_MODE_CLEAR+1),hl ld hl,mcwait ld (MC_WAIT_PRINTER+1),hl ld a,0C3h ;Opcode JP ld hl,mcsend ld (MC_SEND_PRINTER),a ld (MC_SEND_PRINTER+1),hl jp 6E00h ;weiter mit Dobbertin-RamDisk Initialisierung copyanf: .PHASE 0AE58h esc1tab:db 6 ;neuer Eintrag in ESC-mit-Parameter-Tabelle db 'c' dw 04A8h ;Hintergrundfarbe db 'b' dw 049Ch ;Schriftfarbe db 'a' dw attrib ;neu: Schriftart Master-Control db 'Y' dw 0480h ;Cursor positionieren db '3' dw 04BEh ;Bildschirmmodus db '2' dw 04B4h ;Zeichensatz attrib: call 0455h ;naechstes Byte vom Bildschirm ld (0BEE9h),a ;und merken fuer zukuenftige Ausgaben jp 044Eh ;ESC-Folge beenden invon: ld hl,0BEE9h set 1,(hl) ;Invers einschalten jp 044Eh invoff: ld hl,0BEE9h ;Invers ausschalten res 1,(hl) jp 044Eh ulon: ld hl,0BEE9h ;Unterstreichen einschalten set 3,(hl) jp 044Eh ;ESC-Folge beenden uloff: ld hl,0BEE9h res 3,(hl) jp 044Eh ;ESC-Folge beenden ;neue SCR_MODE_CLEAR: Nur bei Modus 2 aktivieren scrmd: call SCR_GET_MODE ld hl,outus ld (TXT_WRITE_CHAR+1),hl cp 2 call nz,TXT_RESET jp SCR_CLEAR ;###### Zeichen in A an Spalte H Zeile L anzeigen outus: ld bc,8000h ;RAM-Font ;****** relevante Matrix aus Zeichensatztabelle holen anhand Code in A ex de,hl ;DE := Koordinaten ld l,a ld h,0 ;HL := Zeichencode add hl,hl add hl,hl add hl,hl add hl,bc ;BC := Zeichensatzadresse push hl ;(SP) := Charaktermatrix ;****** Spalte D Zeile E in Bildschirmposition umrechnen ld a,e add a,a add a,a add a,e ;Zeile * 5 (<120) rlca rlca rlca rlca ;Zeile * 8 ld e,a and 0F8h ;Lower Byte add a,d ;Spalte addieren ld d,a ld a,e ;Higher Byte ld e,d adc a,0 ;]bertrag ld d,a ;DE := Zeichenposition ;koennte ersetzt werden durch "ld hl,(FirmWare-Variable)" ; aber -> dann ROM-Versionsabhaengig di ;keine Kollission mit Bildschirmausgabe im Interrupt ld bc,0BC0Ch out (c),c ld b,0BFh in h,(c) ld bc,0BC0Dh out (c),c ld b,0BFh in l,(c) ;HL := CRTC - Bildschirmoffset add hl,hl ;HL := CPU - Bildschirmoffset ei add hl,de ;HL := CPU-Zeichenadresse ld a,h and 07h ;2KB Bereich or 040h ;in Segment [4000..7FFF] bei CP/M plus ld h,a pop de ;DE := Charaktermatrix ;###### Zeichen ausgeben DE:= Charaktermatrix, HL:=Screenadresse ;(0BEE9h): Bit0=Durchgestrichen, Bit1=Invers, Bit2=gerastert ;Bit3=Unterstrichen, Bit4=Tief, Bit5=Hoch, Bit6=Fett, Bit7=Kursiv ld bc,(0BEE9h) ;C:=Video-Attribut B:=Erlaubnis ld a,b and a jp z,tpos ;Attribute z.B. wegen Statuszeile gesperrt ld a,c and 0FDh ;nichts au~er Invers? ld a,c jp z,tinvers push hl ex de,hl ;HL := Zeichenmatrix ld de,tbuffer ;DE := 8 Byte Puffer and 30h jr nz,tshift ld bc,8 ;Matrix f}r weitere Mainpulationen in Puffer ldir jr tnoshif tshift: sub 10h ;Matrix in Puffer und dabei komprimieren jr nz,tnotief ld (de),a ;Voraussetzung: A = 0 inc de ld (de),a inc de call tkompr ;Tiefstellen jr tnoshif tnotief:sub 10h jr nz,tnohoch call tkompr ;Hochstellen ld (de),a ;Voraussetzung: A = 0 inc de ld (de),a jr tnoshif tnohoch:xor a ld (de),a inc de call tkompr ;Hoch + Tiefstellen = zentrieren ld (de),a tnoshif:ld a,(0BEE9h) ld c,a and 0C0h ;Fett oder Kursiv verwendet? ld a,c jr z,tnofeku add a,a jr nc,tnokur ld hl,tbuffer ;Kursive Darstellung srl (hl) ;3 Rasterzeilen nach rechts rutschen inc hl srl (hl) inc hl srl (hl) ld hl,tbuffer+6 ;3 Rasterzeilen bleiben sla (hl) ;2 Rasterzeilen nach links rutschen inc hl sla (hl) tnokur: add a,a jr nc,tnofett ld hl,tbuffer ;Fettschrift einschalten ld b,4 tf2: ld a,(hl) add a,a or (hl) ld (hl),a inc hl ld a,(hl) add a,a or (hl) ld (hl),a inc hl djnz tf2 tnofett:ld a,c tnofeku:and 09 ;Unterstreichen oder Durchstreichen jr z,tnoduun ld a,0FFh bit 0,c jr z,tnodu ld (tbuffer+3),a ;Durchstreichen tnodu: bit 3,c jr z,tnoduun ld (tbuffer+7),a ;Unterstreichen tnoduun:bit 2,c jr z,tlatt ld hl,tbuffer ;Rastern ld bc,0455h ;Schleifenz{hler + Raster tras: ld a,c and (hl) ld (hl),a inc hl ld a,c rrca ;Raster invertieren -> Schachbrett and (hl) ld (hl),a inc hl djnz tras tlatt: pop hl ;HL := Bildschirmadresse ld de,tbuffer ;DE := Zeichenmatrix ld a,(0BEE9h) ;A := Invers-Attribut tinvers:and 02 ;Zeichen auf Bildschirm darstellen jr z,tpos ld a,0FFh tpos: ld c,a ;C := Invers-Maske ld b,4 tpos2: ld a,(de) ;Zeichenmatrix-Zeile inc de xor c ld (hl),a ;in Bildschirm set 3,h ;n{chste (ungerade!) Rasterzeile ld a,(de) ;Zeichenmatrix-Zeile inc de xor c ld (hl),a ;in Bildschirm ld a,h ;n{chste Rasterzeile add a,8 ld h,a djnz tpos2 ret ;****** Matrix in Puffer kopieren und dabei komprimieren tkompr: ldi inc hl ldi ldi inc hl ldi ldi ldi ret ;****** Zwischenspeicher tbuffer:ds 8,0 ;8 Bytes Raum f}r aktuelle Zeichenmatrix ;****** Bildschirm zuruecksetzen scres: call SCR_RESET ld hl,scrmd ld (SCR_MODE_CLEAR+1),hl ret ;****** 8. Druckerbit: 8255 PIO Port C Bit 5 (CAS-Daten) (Pin 12) ; auch auf 8. Datenbit des Drucker-Steckers abzweigen (Pin 9) ; und dortige Masseverbindung auftrennen mcwait: ld bc,0032h mc2: push bc ld c,a ld b,0F5h in a,(c) rla rla ld a,c pop bc jr nc,mcsend djnz mc2 dec c jr nz,mc2 or a ret mcsend: push bc ld c,a ;Datenbyte mit 8 Bit add a,a ld a,5 adc a,a ;Bit 5,Port C setzen wie Datenbyte, Bit 7 ld b,0F7h out (c),a ;PIO-Control ld a,c ld b,0EFh ;Druckerport and 7Fh out (c),a ;Daten anlegen or 80h di ;Strobe m|glichst kurz out (c),a ;Strobe Date and 7Fh ei out (c),a ;Strobe zur}cknehmen ld a,c ;8. Bit restaurieren pop bc scf ;]bertragung erfolgreich ret .DEPHASE copyend: ;================================================================ end