;********************************************************** ;* SCRKOMP.ASM * ;* Ein Programm zur Komprimierung des Inhalts des Bild- * ;* schirmspeichers zur Speicherung auf Diskette. Dieses * ;* Programm wurde auf dem JOYCE+/PCW 8512 unter CP/M 3 * ;* Version 1.4 (J14GCPM3.EMS) erstellt. Bei Verwendung * ;* einer anderen CP/M-Version m}ssen die Adressen der * ;* verwendeten Systemroutinen evtl. angepa~t werden. * ;* * ;* (c) 1989 by NoFi * ;********************************************************** ; ;*** EQUATES ; SCR_RUN EQU 000E9H ;XBIOS-Funktion #35 SCR_WRITE EQU 015AAH ;System-Routine SCR_SET_ATTR EQU 015C4H ;System-Routine SCR_NORM EQU 015E5H ;System-Routine SCR_INVERS EQU 015EBH ;System-Routine SCR_CHAR_POS EQU 0169CH ;System-Routine SCR_GET_M EQU 01764H ;System-Routine MTXBUF EQU 01770H ;Matrix-Puffer MTXRAM EQU 0B800H ;Start Character Matrix RAM XBIOS EQU 0FC5AH ;Einsprung JOYCE-XBIOS ; ORG 0F300H ;Programm-Start ; ;*** Initialisierungsroutine, setzt Z{hler und Koordinaten ;*** auf Default-Werte ; INIT LD HL,0205AH ;Z{hlwerte Zeile/Spalte LD (XCOUNT),HL ;abspeichern LD HL,0 ;Default f}r LD (KOORD),HL ;Koordinaten setzen XOR A,A ;A = 0 LD (BUFCNT),A ;Pufferz{hler LD (RETCDE),A ;und Returncode auf 0 DEC A ;A=255 LD (FLAG),A ;Flag initialisieren RET ;danach zur}ck ; ;*** Aufruf der SAVE-Routine. HL zeigt auf die Adresse des ;*** Record-Puffers im Hauptprogramm (128 Bytes) ; SCALL LD A,(RETCDE) ;Return-Code pr}fen OR A,A ;und Routine nur ausf}hren RET NZ ;wenn RETCDE = 0 LD E,(HL) ;Record-Pufferadresse holen INC HL LD D,(HL) PUSH DE ;und sichern LD BC,SAVE ;Adr. der SAVE-Routine CALL XBIOS ;}ber das XBIOS aufrufen DEFW SCR_RUN ;uns SCR-Environment einsch. POP DE ;Adr. REC.-Puffer zur}ckholen LD HL,FBUFF ;Adr. File-Puffer LD BC,00080H ;Puffergr|~e 128 Bytes LDIR ;in REC-Puffer }bertr. RET ;danach zur}ck ; ;*** SAVE-Routine, wandelt den Inhalt des Bildschirmspei- ;*** chers in ASCII-Zeichen um und speichert diese in den ;*** 'File-Puffer'. Falls eine Umwandlung nicht m|glich, ;*** wird die komplette Matrix abgespeichert ; SAVE CALL SETPAR ;Parameter setzen OR A,A ; = 0? JR Z,BUFFOK ;ja, Pufferadr. o.k. EX DE,HL ;sonst DE=Zieladr. LD HL,00080H ;Offset (128 Bytes) ADD HL,DE ;zur Adresse addieren LD B,0 ;B = 0 PUSH BC ;Anzahl ]berschu~bytes LDIR ;in Puffer }bertragen POP BC ;Anzahl zur}ckholen EX DE,HL ;HL = 1. freier Eintrag BUFFOK EXX ;2. Registersatz aus PUSH BC ;Z{hler und Koordinaten PUSH DE ;sichern LD HL,MTXBUF ;Adresse Matrix-Puffer CALL SCR_GET_M ;und Zeichen holen LD BC,000FFH ;Zeichenz{hler & Flag BASE LD HL,MTXRAM ;Startadresse Matrix-Ram LD DE,00008H ;Matrix-Offset NXTMTX LD A,(MTXBUF) ;1. Zeichen auslesen CP (HL) ;Byte (A) = MTX-Byte? JR Z,BYTEOK ;ja, n{chstes Byte pr}fen INCMTX ADD HL,DE ;sonst Offset addieren DJNZ NXTMTX ;und n{chstes Zeichen pr}fen INC C ;Flag erh|hen JP NZ,MATRIX ;>0? d. Matrix eintragen CALL INVMTX ;sonst Matrix invertieren JR BASE ;und nochmal ; ;*** 1. Byte der Matrix war o.k., nun werden die weiteren ;*** Bytes gepr}ft ; BYTEOK PUSH HL ;Adresse im Matrix-RAM, PUSH DE ;Offsetwert und PUSH BC ;Z{hler/Flag sichern LD BC,MTXBUF ;Adresse Matrix-Puffer DECE DEC E ;letztes Zeichen? JR Z,FOUND ;ja, Zeichen gefunden INC BC ;Zeiger erh|hen INC HL LD A,(BC) ;MTX-Byte aus Puffer CP (HL) ;mit MTX-Byte in RAM vergl. JR Z,DECE ;gleich? d. n{chstes Byte DEC E ;letztes Byte? POP BC ;Z{hler/Flag zur}ckholen POP DE ;Matrix-Offset POP HL ;und Adresse Matrix-RAM JR NZ,INCMTX ;nicht letztes Byte? -> INCMTX CP A,C ;sonst evtl. unterstrichen? JR NZ,INCMTX ;nein, d. n{chstes Zeichen INC C ;Flag pr}fen LD C,1 ;Attribute=norm. unterstr. JR Z,SFLAG ;flag o.k? d. pr}fen LD C,3 ;sonst Attribute=inv. unterstr. ; ;*** Hier wird gepr}ft, ob das Ausgabe-Attribute ge{ndert ;*** (und damit auch abgespeichert) werden mu~ ; SFLAG LD A,(FLAG) ;altes Flag holen CP A,C ;und mit neuem Flag vergleichen JR Z,SAVEZ ;wenn gleich, nur Zchn speichern LD A,C ;neues Flag nach A holen LD (FLAG),A ;abspeichern CALL SAVEB ;und in File-Puffer SAVEZ LD A,B ;Zeichen holen NEG ;Zweier-Komplement bilden CP A,5 ;Zeichen <= 4 ? JR C,MATRIX ;ja, als Matrix abspeichern CALL SAVEB ;sonst Zchn in Puffer eintr. NXTCHR POP DE ;Koordinaten und Z{hler POP BC ;zur}ckholen INC E ;Spalte +1 DEC C ;Spaltenz{hler -1 JR NZ,CHKBUF ;wenn >0, d. weiter INC D ;sonst Zeile +1 LD E,C ;Spalte = 0 LD C,05AH ;Spaltenz{hler = 90 DJNZ CHKBUF ;und weiter, bis Zeile 31 LD A,0FFH ;dann A = 255 LD (RETCDE),A ;und Return-Code setzen EXX ;2. Registersatz ein LD C,A ;und Z{hlbyte = 255 LD (HL),01AH ;EOF in Puffer eintragen EXX ;2. Registersatz aus ; ;*** Puffer auf freien Speicherplatz }berpr}fen ; CHKBUF EXX ;2. Registersatz ein BIT 7,C ;Puffer voll? JR Z,BUFFOK ;nein, Puffer-Adr. o.K. LD A,C ;Z{hlbyte -> A AND A,07FH ;evtl. ]berschu~ isolieren EXX ;2. Registersatz aus JR END1 ;und beenden ; ;*** Zeichen wurde gefunden ; FOUND POP BC ;Register zur}ckholen POP DE POP HL INC C ;Flag pr}fen LD C,2 ;Flag auf invers JR NZ,SFLAG ;wenn invers, Flag speichern LD C,0 ;sonst Flag = normal JR SFLAG ;anschlie~end Zeichen speichern ; ;*** Zeichen wurde nicht gefunden, Matrix abspeichern ; MATRIX INC C ;Flag pr}fen CALL NZ,INVMTX ;wenn <>0, Matrix invertieren EXX ;2. Registersatz ein LD (HL),4 ;Flag f}r Matrix INC HL ;Adr. +1 EX DE,HL ;F}r transfer, Zieladr. -> DE LD HL,MTXBUF ;Adr. Matrixpuffer PUSH BC ;Z{hler (FBUFF) sichern LD BC,8 ;Anz. Matrixbytes LDIR ;Matrix in FBUFF eintragen LD HL,9 ;Matrix-Offset (+1) f}r FBUFF POP BC ;Z{hler zur}ckholen ADD HL,BC ;und Offset addieren LD B,H ;neuen Z{hlerwert LD C,L ;eintragen EX DE,HL ;Adresse FBUFF wieder -> HL EXX ;2. Registersatz aus JR NXTCHR ;und Koordinaten pr}fen ; ;*** Aufruf der LOAD-Routine. HL zeigt auf die Adresse des ;*** Record-Puffers im Hauptprogramm (128 Bytes) ; LCALL LD A,(RETCDE) ;Routine nur aufrufen, wenn OR A,A ;Return-Code = 0 RET NZ LD E,(HL) ;Adresse des Record-Puffers INC HL ;vom Anwenderprogr. abholen LD D,(HL) ;und in DE sichern LD B,A ;B = 0 LD A,(BUFCNT) ;evtl. Rest (Offset) im Puffer LD C,A ;nach C LD HL,FBUFF ;Startadr. File-Puffer ADD HL,BC ;und Offset addieren EX DE,HL ;danach Daten vom Record-Puffer LD BC,080H ;in File-Puffer }bertragen LDIR LD BC,LOAD ;dann }ber's XBIOS die CALL XBIOS ;LOAD-Routine aufrufen DEFW SCR_RUN RET ;danach wieder zur}ck ; ;*** LOAD-Routine, wandelt den komprimierten Inhalt des ;*** 'File-Puffers' in 'normale Matrixes' um und }ber- ;*** tr{gt diese in den Bildschirmspeicher ; LOAD CALL SETPAR ;Parameter setzen ADD A,080H ;und Pufferl{nge addieren LD C,A ;= neuer Pufferz{hler LD B,0 ;und B auf 0 NCHAR LD A,(HL) ;sonst Zeichen holen INC HL ;Puffer-Zeiger +1 EXX ;und 2. Registersatz aus PUSH BC ;Koordinatenz{hler sichern CP A,4 ;Zeichen < 4? JR C,ATTRIB ;d. Attribute setzen PUSH DE ;Koordinaten sichern JR Z,NOCHAR ;wenn 4, d. Matrix speichern LD C,A ;sonst Character -> C CALL SCR_WRITE ;und Zeichen ausgeben CHREND POP DE ;Koordinaten und POP BC ;Koordinatenz{hler holen INC E ;Spalte +1 DEC C ;Spaltenz{hler -1 JR NZ,CHECKB ;n{chstes Zeichen lesen INC D ;wenn letzte Spalte, Zeile +1 LD E,C ;Spalte = 0 LD C,05AH ;Spaltenz{hler = 90 DJNZ CHECKB ;und n{chstes Zeichen lesen LD A,0FFH ;wenn alle Zeichen geladen, LD (RETCDE),A ;Return-Code auf 255 RET ;und zur}ck ; ;*** Puffer }berpr}fen, ob noch Daten vorhanden ; CHECKB EXX ;2. Registersatz ein DEC C ;Z{hler -1 JR NZ,NCHAR ;wenn noch Daten, nochmal EXX ;2. Registersatz aus ; ;*** Routine beenden und auf n{chsten Aufruf warten. Die ;*** aktuellen Z{hler und Koordinaten werden gesichert ; ENDR XOR A,A ;A = 0 END1 LD (BUFCNT),A ;Puffer-Offset setzen LD (XCOUNT),BC;Koordinatenz{hler und LD (KOORD),DE ;Koordinaten sichern RET ;dann zur}ck ; ;*** Matrix wurde gefunden und mu~ abgespeichert werden, ;*** sofern sie komplett im Puffer vorhanden ist. ; NOCHAR EXX ;2. Registersatz ein LD A,C ;Pufferz{hler pr}fen, ob SUB A,09 ;Matrix noch vollst. im Puffer JR NC,MTXOK ;ja? d. Matrix }bertragen DEC HL ;HL wieder auf Flag setzen LD DE,FBUFF ;MTX-Flag und Matrix-Bytes an den LD A,C ;Beginn des Puffers setzen, Z{hler LDIR ;in A sichern EXX ;d. 2. Registersatz aus POP DE ;Register zur}ck POP BC JR END1 ;und abbrechen ; ;*** Matrix ist komplett, abspeichern ; MTXOK INC A ;A auf neuen Z{hlerstand LD C,A ;und Z{hler setzen PUSH HL ;Pufferadr. sichern EXX ;2. Registersatz aus CALL SCR_CHAR_POS ;Screen-Adr. ausrechnen POP HL ;Pufferadr. zur}ck CALL SCR_NORM ;und Matrix }bertragen PUSH HL ;neue Pufferadr. in EXX ;HL' }bertragen POP HL EXX ;2. Registersatz wieder aus JR CHREND ;evtl. n{chstes Zeichen holen ; ;*** Ausgabe-Attribute mu~ ge{ndert werden ; ATTRIB RLCA ;Attribute-code erzeugen CALL SCR_SET_ATTR ;und setzen POP BC ;Z{hler zur}ck JR CHECKB ;evtl. n{chstes Zeichen holen ; ;*** Z{hler und Koordinaten werden in die entspr. Register ;*** }bernommen ; SETPAR LD BC,(XCOUNT);Koordinatenz{hler und LD DE,(KOORD) ;Koordinaten holen EXX ;2.Registersatz ein LD HL,FBUFF ;Startadresse Puffer LD A,(BUFCNT) ;und Pufferz{hler laden LD C,A ;Z{hler -> C RET ;und zur}ck ; ;*** Matrix invertieren ; INVMTX LD HL,MTXBUF ;Adresse Matrix-Puffer LD D,H ;auch nach DE LD E,L JP SCR_INVERS ;und Matrix invertieren ; ;*** Byte in File-Buffer eintragen ; SAVEB EXX ;2. Registersatz ein LD (HL),A ;Byte abspeichern INC HL ;Adresse und Z{hler INC C ;erh|hen EXX ;Registersatz aus RET ;und zur}ck ; ;*** DATA-Area ; RETCDE DEFS 1 ;reserv. f}r Return-Code FLAG DEFS 1 ;reserv. f}r Attribute-Flag BUFCNT DEFS 1 ;reserv. f}r Puffer-Z{hler XCOUNT DEFS 2 ;reserv. f}r Z/S Z{hler KOORD DEFS 2 ;reserv. f}r SCR-Koordinaten FBUFF DEFS 140 ;reserv. f}r Record-Puffer ; END