; ----------------------------------------------------------------------------
; - Bernd Hbenett (RxT) 27.06.1995 Obertshausen                             -
; - Email (internet): huebenet@stud.uni-frankfurt.de                         -
; -                                                                          -
; - 27.06.1995 spt Abends                                                   -
; - Die Umsetzung des Lauflngenkodierers begonnen                           -
; - 28.06.1995 8:30                                                          -
; - Suzy hat eben angerufen.                                                 -
; - Ein schner Weckdienst.                                                  -
; - 29.06.1995 7:10                                                          -
; - Scheint zu funktionieren, auch die Bugs  ;-)                             -
; - angeblich wurde Time.R16 auf 75 KByte komprimiert. Original 128 Kbyte.   -
; - Irgendwas stimmte doch noch nicht. Die Routinen so verndert das sie     -
; - jetzt nicht meht Bytes sondern Words komprimieren. Es funktioniert jetzt -
; - alles und Time.R16 ist jetzt nur noch ca. 71 Kbyte gro.                 -
; - Speicherroutinen integriert. Aus *.R16 wird ein *.C16                    -
; - Das R steht fr Raw und das C fr Compressed. 16 ist die Farbtiefe       -
; ----------------------------------------------------------------------------

cnecin          EQU 8
logbase         EQU 3
super           EQU 32
vsync           EQU 37

start:          DC.W $A00A

                pea     0
                move.w  #super,-(SP)
                trap    #1
                addq.l  #6,SP
                move.l  D0,ssp

                move.w  #2,-(SP)        ; Bildschirmadressen holen
                trap    #14
                addq.l  #2,SP
                move.l  D0,oldphys      ; Bildschirmadresse in oldphys speichern
                move.w  #3,-(SP)
                trap    #14
                addq.l  #2,SP
                move.l  D0,oldlog

                move.l  #screen+256,D0  ; Neue Video Adresse
                and.l   #$FFFFFF00,D0
                move.l  D0,buffscr

                move.b  D0,$FFFF820D
                lsr.l   #8,D0
                move.b  D0,$FFFF8203
                lsr.l   #8,D0
                move.b  D0,$FFFF8201

                bsr     Save_System

                lea     Videl_320_200_True,A0
                bsr     Set_Res

; Erst mal schauen welche Words wie oft vor kommen
compress:       lea     bild,A0
                lea     anzahl_tab,A1
                clr.l   D1
                move.l  #64000,D0
anzahl_loop:    move.w  (A0)+,D1
                DC.W $5271,$1A00 ; add.w #1,0(a1,d1.l*2)
                subq.l  #1,D0
                bne.s   anzahl_loop

                lea     anzahl_tab,A0
                clr.l   D2              ; Pointer
                move.w  #0,D0           ; Scleifenzhler
                move.w  #65535,D1       ; mit maximal Wert initialisieren
anzahl_loop_2:  move.w  (A0)+,D3        ; Wert holen
                cmp.w   D1,D3           ; und vergleichen
                bhi.s   zu_gro         ; wenn D3 grer dann verzweige
                move.w  D3,D1           ; neuer Wert nach D1
                move.w  D0,D2           ; Position festhalten
zu_gro:        add.w   #1,D0
                cmp.w   #65535,D0
                bne.s   anzahl_loop_2

; in D2 steht jetzt unser Escape-Word
; es hat die Eigenschaft das es wenigsten oder sogar gar nicht
; in den zu komprimierenden Daten vorkommt.

; Kennungen:
; Daten (bei weniger als 4mal dem selben Zeichen)
; Escape-Word,Datum,Anzahl (bei mehr als 3mal dem selben Zeichen)
; Escape-Word,Escape-Word (Endkennung)
; Aufbau von coded_data:
; 1 Word = Das Escape-Word


                lea     bild,A0
                lea     coded_data,A1
                move.w  D2,(A1)+        ; Escape-Byte
                moveq   #0,D5
rle_loop:       move.w  (A0),D3
                move.w  D3,D4
                swap    D3
                move.w  D4,D3
                cmp.l   0(A0),D3
                bne.s   no_kompress
                cmp.l   4(A0),D3        ; 4mal der selbe Wert ??
                bne.s   no_kompress
komprimieren:   move.w  #4,D4           ; Schleifenzhler
                addq.l  #4,D5
                adda.l  #8,A0
komp_loop:      cmp.w   (A0)+,D3
                bne.s   not_equal

                addq.l  #1,D5
                cmp.l   #64000,D5
                bhi.s   not_equal

                addq.w  #1,D4
                cmp.w   #65535,D4       ; nicht mehr als 65535
                bne.s   komp_loop
not_equal:      move.w  D2,(A1)+        ; Escape
                move.w  D3,(A1)+        ; Datum
                move.w  D4,(A1)+        ; Anzahl
                bra.s   check_loop
no_kompress:    move.w  D3,(A1)+        ; Datum
                addq.l  #1,D5
                addq.l  #2,A0
check_loop:     cmp.l   #64000,D5
                bls.s   rle_loop
                move.w  D2,(A1)+        ; Endkennung
                move.w  D2,(A1)+        ; Endkennung

                lea     coded_data,A0   ; Lnge der
                suba.l  A0,A1           ; komprimierten Daten ermitteln

                move.w  #0,-(SP)
                pea     filename
                move.w  #$3C,-(SP)      ; Fcreate
                trap    #1
                addq.l  #8,SP
                move.w  D0,handle

                pea     coded_data
                move.l  A1,-(SP)
                move.w  handle,-(SP)
                move.w  #$40,-(SP)
                trap    #1
                lea     $0C(SP),SP

                move.w  handle,-(SP)
                move.w  #$3E,-(SP)
                trap    #1
                addq.l  #4,SP

; Der Dekomprimierer
                lea     coded_data,A0
                movea.l buffscr,A1
                move.w  (A0)+,D0        ; Escape-Byte
dek_loop:       move.w  (A0)+,D1        ; Coded_data -> D1.W
                cmp.w   D1,D0           ; Ist es ein Escape-Word
                bne.s   nicht_komp      ; springe wenn normales Datum
                move.w  (A0)+,D2        ; nchstes Word nach D2.W
                cmp.w   D0,D2           ; wenn Escape-Word
                beq.s   dek_ende        ; dann dekompression beenden
                move.w  (A0)+,D3        ; Anzahl der Daten
dek_fill:       move.w  D2,(A1)+        ; in D2 steht das Datum
                dbra    D3,dek_fill
                bra.s   dek_loop
nicht_komp:     move.w  D1,(A1)+
                bra.s   dek_loop
dek_ende:

                move.w  #8,-(SP)
                trap    #1
                addq.l  #2,SP

raus:           bsr     restore_system
                bsr     wait_vsync
                move.l  oldlog,D0
                move.b  D0,$FFFF820D
                lsr.l   #8,D0
                move.b  D0,$FFFF8203
                lsr.l   #8,D0
                move.b  D0,$FFFF8201

                move.l  ssp,-(SP)
                move.w  #super,-(SP)
                trap    #1
                addq.l  #6,SP

                clr.w   -(SP)
                trap    #1

; ------------------------------------------
; ----- A U F   V S Y N C   W A R T E N ----
; ------------------------------------------

wait_vsync:     move.l  D0,-(SP)
                move.l  $0462,D0
wait_wait_x:    cmp.l   $0462,D0
                beq.s   wait_wait_x
                move.l  (SP)+,D0
                rts

; ---------------------------------------------
; -------- S E T  V I D E O  M O D E ----------
; ---------------------------------------------
; Parameter:
;             A0.L : Adresse der Betriebsart
;                      (aus der Tabelle)
; ---------------------------------------------

Set_Res:        move.b  #2,$FFFF820A.w  ; Horloge Interne
                clr.b   $FFFF8265.w     ; Dcalage Pixel Nul
                addq.l  #4,A0
                move.w  (A0)+,$FFFF820E.w ; Offset bis zur nchsten Zeile (Words)
                move.w  (A0)+,$FFFF8210.w ; Lnge der sichtbaren Zeile (Words)
                move.w  (A0)+,D0        ; Rsolution ST
                move.w  (A0)+,D1        ; Rsolution FALCON

                move.w  D1,$FFFF8266.w  ; Rsolution FALCON
                tst.w   (A0)+
                beq.s   FalconRez
                move.b  D0,$FFFF8260.w  ; Rsolution ST
                move.w  -8(A0),$FFFF8210.w ; Largeur d'une ligne en mots
FalconRez:
;                btst    #7,$FFFF8006.w  ; Ecran VGA ?
;                beq.s   R_Ok            ; Si non,saut...
;                adda.w  #16*2,A0
R_Ok:           move.w  (A0)+,$FFFF8282.w ; HHT-Synchro
                move.w  (A0)+,$FFFF8284.w ; Fin du dcodage de la ligne
                move.w  (A0)+,$FFFF8286.w ; Dbut du dcodage de la ligne
                move.w  (A0)+,$FFFF8288.w ; Overscan links
                move.w  (A0)+,$FFFF828A.w ; Overscan rechts
                move.w  (A0)+,$FFFF828C.w ; HSS-Synchro
                move.w  (A0)+,$FFFF828E.w ; HFS
                move.w  (A0)+,$FFFF8290.w ; HEE
                move.w  (A0)+,$FFFF82A2.w ; VFT-Synchro
                move.w  (A0)+,$FFFF82A4.w ; Fin du dcodage de l'image
                move.w  (A0)+,$FFFF82A6.w ; Dbut du dcodage de l'image
                move.w  (A0)+,$FFFF82A8.w ; Overscan oben
                move.w  (A0)+,$FFFF82AA.w ; Overscan unten
                move.w  (A0)+,$FFFF82AC.w ; VSS-Synchro
                move.w  (A0)+,$FFFF82C0.w ; Indique rsolution FALCON
                move.w  (A0),$FFFF82C2.w ; Informations rsolution
                rts

; ---------------------------------------------
; ----------  V I D E O  S A V E --------------
; ---------------------------------------------

Save_System:    lea     Old_System,A0
                move.b  $FFFF8007.w,(A0)+ ; Configuration 68030
                move.b  $FFFF820A.w,(A0)+ ; Synchronisation vido
                move.w  $FFFF820E.w,(A0)+ ; Offset pour prochaine ligne
                move.w  $FFFF8210.w,(A0)+ ; Largeur d'une ligne en mots
                move.b  $FFFF8260.w,(A0)+ ; Rsolution ST
                move.b  $FFFF8265.w,(A0)+ ; Dcalage Pixel
                move.w  $FFFF8266.w,(A0)+ ; Rsolution FALCON
                move.w  $FFFF8282.w,(A0)+ ; HHT-Synchro
                move.w  $FFFF8284.w,(A0)+ ; Fin du dcodage de la ligne
                move.w  $FFFF8286.w,(A0)+ ; Dbut du dcodage de la ligne
                move.w  $FFFF8288.w,(A0)+ ; Overscan gauche
                move.w  $FFFF828A.w,(A0)+ ; Overscan droit
                move.w  $FFFF828C.w,(A0)+ ; HSS-Synchro
                move.w  $FFFF828E.w,(A0)+ ; HFS
                move.w  $FFFF8290.w,(A0)+ ; HEE
                move.w  $FFFF82A2.w,(A0)+ ; VFT-Synchro
                move.w  $FFFF82A4.w,(A0)+ ; Fin du dcodage de l'image
                move.w  $FFFF82A6.w,(A0)+ ; Dbut du dcodage de l'image
                move.w  $FFFF82A8.w,(A0)+ ; Overscan haut
                move.w  $FFFF82AA.w,(A0)+ ; Overscan bas
                move.w  $FFFF82AC.w,(A0)+ ; VSS-Synchro
                move.w  $FFFF82C0.w,(A0)+ ; Reconnaissance ST/FALCON
                move.w  $FFFF82C2.w,(A0)+ ; Informations rsolution

                lea     $FFFF8240.w,A1  ; Palette ST
                moveq   #8-1,D0         ; 8 longs...
Save_ST_Palette:
                move.l  (A1)+,(A0)+     ; Sauve 2 couleurs
                dbra    D0,Save_ST_Palette ; Boucle les 16 mots !

                lea     $FFFF9800.w,A1  ; Palette FALCON
                move.w  #256-1,D0       ; 256 longs...
Save_FALCON_Palette:
                move.l  (A1)+,(A0)+     ; Sauve 1 couleur
                dbra    D0,Save_FALCON_Palette ; Boucle les 256 longs !
                rts

; --------------------------------------------
; ------  V I D E O   R E S T O R E ----------
; --------------------------------------------

restore_system: move    #$2700,SR       ; Interrupts sperren
                lea     Old_System,A0   ; Espace de sauvegarde
                move.b  (A0)+,$FFFF8007.w ; Configuration 68030
                move.b  (A0)+,$FFFF820A.w ; Video-Syncronisation
                move.w  (A0)+,$FFFF820E.w ; Offset pour prochaine ligne
                move.w  (A0)+,$FFFF8210.w ; Largeur d'une ligne en mots
                move.b  (A0)+,D0        ; Rsolution ST
                move.b  (A0)+,$FFFF8265.w ; Dcalage Pixel
                move.w  (A0)+,D1        ; Rsolution FALCON
                move.w  (A0)+,$FFFF8282.w ; HHT-Synchro
                move.w  (A0)+,$FFFF8284.w ; Fin du dcodage de la ligne
                move.w  (A0)+,$FFFF8286.w ; Dbut du dcodage de la ligne
                move.w  (A0)+,$FFFF8288.w ; Overscan gauche
                move.w  (A0)+,$FFFF828A.w ; Overscan droit
                move.w  (A0)+,$FFFF828C.w ; HSS-Synchro
                move.w  (A0)+,$FFFF828E.w ; HFS
                move.w  (A0)+,$FFFF8290.w ; HEE
                move.w  (A0)+,$FFFF82A2.w ; VFT-Synchro
                move.w  (A0)+,$FFFF82A4.w ; Fin du dcodage de l'image
                move.w  (A0)+,$FFFF82A6.w ; Dbut du dcodage de l'image
                move.w  (A0)+,$FFFF82A8.w ; Overscan haut
                move.w  (A0)+,$FFFF82AA.w ; Overscan bas
                move.w  (A0)+,$FFFF82AC.w ; VSS-Synchro
                move.w  (A0)+,$FFFF82C0.w ; Reconnaissance ST/FALCON
                move.w  (A0)+,$FFFF82C2.w ; Informations rsolution
                move.w  D1,$FFFF8266.w  ; Fixe rsolution FALCON...
                btst    #0,$FFFF82C0.w  ; Rsolution FALCON ?
                bne.s   Falcon_Rez      ; Si oui,saut !
                move.b  D0,$FFFF8260.w  ; Fixe rsolution ST...
Falcon_Rez:     lea     $FFFF8240.w,A1  ; ST-Farbpalette restaurieren
                moveq   #7,D0           ; 8 Langwrter...
Rest_ST_Palette:
                move.l  (A0)+,(A1)+     ; immer 2 Farben auf einmal
                dbra    D0,Rest_ST_Palette

                lea     $FFFF9800.w,A1  ; FALCON-Farbpalette restaurieren
                move.w  #255,D0         ; 256 Langwrter
Rest_FALCON_Palette:
                move.l  (A0)+,(A1)+     ; eine Farbe nach der anderen
                dbra    D0,Rest_FALCON_Palette
                move    #$2000,SR       ; Interrupts freigeben
                rts

                DATA
Videl_320_200_True:
                DC.L 320*200*16/8+256 * Gnral
                DC.W 0,320,0,$0100
                DC.W 0          * Flag Ordre

                DC.W 254,203,39,46,143,216,0,0 * RVB
                DC.W 625,613,47,127,527,619
                DC.W $0181,%0

                DC.W 198,150,15,682,139,150,0,0 * VGA 47 Hz
                DC.W 1337,1300,100,315,1115,1333
                DC.W $0186,%101
                EVEN
filename:       DC.B 'Time.C16',0
                EVEN
bild:           IBYTES 'TIME.R16'
                BSS
                EVEN
anzahl_tab:     DS.W 65535
coded_data:     DS.L 60000      ; 240 KByte reservieren
                EVEN
                DS.B 256
ssp:            DS.L 1
oldlog:         DS.L 1
handle:         DS.L 1
oldphys:        DS.L 1
oldmode:        DS.L 1
buffscr:        DS.L 1
Old_System:     DS.L 500        ; Buffer fr altes System
                EVEN
                DS.B 256
screen:         DS.L 38400
                END
