**************************************
* Screen: Init- und Helper-routines  *
* (c) 1994 Bastian Schick            *
*****************
* screen        *
*****************
* Objekt-Defs   *
NEXT_OBJ         EQU 1
***************************************
* BitMap oder Scaled BitMap - Objekte *
***************************************
                RSRESET
                RS.w obj_bm_type                ; Type
                RS.w obj_bm_l                   ; Gre des Objektes (fr MakeOBL)
                RS.l obj_bm_data                ; Data
                RS.w obj_bm_x                   ; X
                RS.w obj_bm_y                   ; Y pos in Halbzeilen
                RS.w obj_bm_height              ; Hhe ODER cc bei BRANCH OBJECT
                RS.w obj_bm_link                ; Abstand zum Nchsten Objekt in Objekten
                RS.b obj_bm_bits                ; Bits pro Pixel
                RS.b obj_bm_pitch               ; Pitch
                RS.w obj_bm_dwidth              ; Breite in Phrases
                RS.w obj_bm_iwidth              ; Bildbreite (sichtbar)
                RS.b obj_bm_cindex              ; Farb-Offset
                RS.b obj_bm_flags               ; Flags
                RS.w obj_bm_firstpx             ; FirstPixel
obj_bm_len      EQU RSCOUNT
                RS.b obj_dummy1
                RS.b obj_sc_rem
                RS.b obj_sc_vscale
                RS.b obj_sc_hscale              ; Ergnzungen fr Scaled BitMap
obj_sc_len      EQU RSCOUNT

**************
* GPU-Object *
**************
                RSRESET
                RS.w obj_gp_type
                RS.w obj_gp_l                   ; Gre des Objektes (fr MakeOBL)
                RS.l obj_gp_data1
                RS.l obj_gp_data2
                RS.w obj_gp_link

obj_gp_len      EQU RSCOUNT
*****************
* Branch-Object *
*****************
                RSRESET
                RS.w obj_br_type
                RS.w obj_br_l                   ; Gre des Objektes (fr MakeOBL)
                RS.w obj_br_y
                RS.w obj_br_cc                  ; Bedingung
                RS.w obj_br_link,2
obj_br_len      EQU RSCOUNT

BRA_OBJ         MACRO ; y_pos,cc,dest
                dc.w 3,obj_br_len
                dc.w \1         ; y
                IFNE "\2"="<"
                dc.w 1
                ELSE
                IFNE "\2"=">"
                dc.w 2
                ELSE
                IFNE "\2"="="
                dc.w 0
                ENDIF
                ENDIF
                ENDIF
                dc.w \3,NEXT_OBJ
                ENDM

***************
* Stop-Object *
***************
                RSRESET
                RS.w obj_st_type
                RS.w obj_st_l
                RS.w obj_st_int
                RS.l obj_st_data1
                RS.l obj_st_data2
obj_st_len      EQU RSCOUNT
*****************
*    MakeOBL    *
MakeOBL:          movem.l d0-a4,-(sp)

                  move.l  #$FF000000,d4

                  lea     ob_list0(a6),a0       ; original
                  lea     ob_list(a6),a1        ; Zieladresse
                  lea     (a1),a4          ; start merken
                  moveq   #0,d7            ; object counter

                  lea     Objekte(pc),a2    ; source

loop_mo:          lea     (a2),a3          ; Ptr auf akt. Objekt retten
                  movem.w (a2)+,d1/d5      ; Type
                  tst.w   d1
                  bpl.s   ok_mo
                  cmp.w   #$AFFE,d1
                  beq     exit_mo
                  lea     -4(a2,d5.w),a2
                  bra.s   loop_mo

ok_mo:            addq.w  #1,d7
                  and.w   #7,d1
                  ext.l   d1
                  move.w  d1,d0
                  subq.w  #2,d0
                  bmi     bm_sc_mo
                  beq     gpu_mo           ; 2=GPU-Object
                  subq.w  #2,d0
                  bmi.s   branch_mo        ; 3=Branch Object
* Stop-Objekt erzeugen
                  moveq   #1,d0
                  and.w   (a2)+,d0
                  lsl.w   #3,d0
                  or.w    d0,d1            ; Interrupt Flag
                  movem.l (a2)+,d0/d2

                  lsl.l   #4,d2
                  or.l    d2,d1
                  move.l  d0,(a0)+
                  move.l  d1,(a0)+
                  lea     24(a0),a0
                  lea     32(a1),a1
                  bra.s   loop_mo
* branch_object
branch_mo:        move.w  #$07FF,d0
                  and.w   (a2)+,d0
                  lsl.w   #3,d0
                  or.w    d0,d1            ; Ypos
                  moveq   #7,d0
                  and.w   (a2)+,d0
                  swap    d0
                  lsr.l   #2,d0
                  or.l    d0,d1            ; CC

                  move.l  a1,d3            ; akt. Pos merken
                  move.w  (a2)+,d0         ; nchstes Objekt falls CC true
                  bpl.s   ok_bra_mo
                  neg.w   d0
                  move.l  a4,d3            ; sonst absolute
ok_bra_mo:        asl.w   #5,d0            ; * 32
                  ext.l   d0
                  add.l   d3,d0
                  lsr.l   #3,d0
                  ror.l   #8,d0
                  move.l  d0,d3
                  and.l   d4,d0
                  or.l    d0,d1            ; Link (24..31)
                  move.l  d3,d0
                  and.l   #$00FFFFFF,d0
                  move.l  d0,(a0)+
                  move.l  d1,(a0)+

                  move.w  #($07FF<<3)|3,d1 ; Branch Always
                  ext.l   d1
                  move.w  (a2)+,d0         ; nchstes Objekt
                  asl.w   #5,d0            ; * 32
                  ext.l   d0
                  add.l   a1,d0
                  lsr.l   #3,d0
                  ror.l   #8,d0
                  move.l  d0,d3
                  and.l   d4,d0
                  or.l    d0,d1            ; Link (24..31)
                  move.l  d3,d0
                  and.l   #$00FFFFFF,d0
                  move.l  d0,(a0)+
                  move.l  d1,(a0)+
                  lea     16(a0),a0
                  lea     32(a1),a1
                  bra     loop_mo
* GPU Object
gpu_mo:           movem.l (a2)+,d0/d1
                  and.w #$fff8,d1
                  addq #2,d1
                  swap    d2
                  move.l  d0,(a0)+
                  move.l  d1,(a0)+

                  move.w  #($07FF<<3)|3,d1 ; Branch Always
                  ext.l   d1
                  move.w  (a2)+,d0         ; nchstes Objekt
                  lsl.w   #5,d0            ; * 32
                  ext.l   d0
                  add.l   a1,d0
                  lsr.l   #3,d0
                  ror.l   #8,d0
                  move.l  d0,d3
                  and.l   d4,d0
                  or.l    d0,d1            ; Link (24..31)
                  move.l  d3,d0
                  and.l   #$00FFFFFF,d0
                  move.l  d0,(a0)+
                  move.l  d1,(a0)+
                  lea     16(a0),a0
                  lea     32(a1),a1
                  bra     loop_mo

* BitMap oder Scaled BitMap
bm_sc_mo:         moveq   #$F8,d0
                  and.l   (a2)+,d0         ; Data-Adress (3..23)
                  bpl.s   ok_bm_sc_mo
                  neg.l   d0
                  add.l   a6,d0
ok_bm_sc_mo:      lsl.l   #8,d0            ; an 63..43

                  move.w  (a2)+,d6         ; X
                  and.w   #$0FFF,d6        ; im 2. Phrase 0..11
                  ext.l   d6

                  move.w  (a2)+,d3
                  and.w   #$07FF,d3
                  lsl.w   #3,d3
                  or.w    d3,d1            ; Y-Pos (3..13)

                  moveq   #0,d3
                  move.w  (a2)+,d3
                  and.w   #$03FF,d3
                  swap    d3
                  lsr.l   #2,d3
                  or.l    d3,d1            ; Hhe (14..23)

                  move.w  (a2)+,d3         ; nchstes Objekt
                  lsl.w   #5,d3            ; * 32
                  ext.l   d3
                  add.l   a1,d3
                  lsr.l   #3,d3
                  ror.l   #8,d3
                  move.l  d3,d2            ; Link retten
                  and.l   d4,d3
                  or.l    d3,d1            ; Link (24..31)

                  move.l  d2,d3
                  and.l   #$00FFFFFF,d3
                  or.l    d3,d0
                  move.l  d0,(a0)+
                  move.l  d1,(a0)+

                  moveq   #7,d0
                  and.b   (a2)+,d0
                  ror.w   #4,d0
                  or.w    d0,d6            ; Depth (12..14)

                  moveq   #7,d0
                  and.b   (a2)+,d0
                  swap    d0
                  lsr.l   #1,d0
                  or.l    d0,d6            ; Pitch (15..17)

                  moveq   #0,d0
                  move.w  (a2)+,d0
                  and.w   #$03FF,d0
                  lsl.w   #2,d0
                  swap    d0
                  or.l    d0,d6            ; Dwidth (18..27)

                  moveq   #0,d0
                  move.w  (a2)+,d0
                  and.w   #$03FF,d0
                  ror.l   #4,d0
                  move.l  d0,d1
                  clr.w   d0
                  or.l    d0,d6            ; IWidth (28..31)
                  ext.l   d1               ; und (32..37)

                  moveq   #$7F,d0
                  and.b   (a2)+,d0
                  lsl.w   #6,d0
                  or.w    d0,d1            ; Index (38..44)

                  moveq   #$0F,d0
                  and.b   (a2)+,d0
                  swap    d0
                  lsr.l   #3,d0
                  or.l    d0,d1            ; Flags (45..48)

                  moveq   #$3F,d0
                  and.w   (a2)+,d0

                  add.w   d0,d0
                  swap    d0
                  or.l    d0,d1
                  move.l  d1,(a0)+
                  move.l  d6,(a0)+

                  lea     16(a0),a0
                  lea     32(a1),a1
                  cmp.w   #obj_sc_len,d5   ; Sized Object
                  bne     loop_mo
                  move.l  (a2)+,-12(a0)
;                  move.b  d0,-8(a0)
;                  move.b  d1,-9(a0)
;                  move.b  d2,-10(a0)
;                  clr.b   -11(a0)
                  bra     loop_mo
exit_mo:          clr.l   (a0)+
                  moveq   #4,d0
                  move.l  d0,(a0)+
                  addq.w  #1,d7
                  move.w  d7,count_obj(a6)
                  movem.l (sp)+,d0-a4
                  rts
*****************
*    CopyOBL    *
CopyOBL:          movem.l d1/a0-a1,-(sp)
 move usp,a0
 addq.l #1,a0
 move a0,usp
                  lea     ob_list(a6),a0
                  lea     ob_list0(a6),a1
                  move.w  count_obj(a6),d1

cobl:             move.l  (a1)+,(a0)+
                  move.l  (a1)+,(a0)+
                  move.l  (a1)+,(a0)+
                  move.l  (a1)+,(a0)+
                  move.l  (a1)+,(a0)+
                  move.l  (a1)+,(a0)+
                  move.l  (a1)+,(a0)+
                  move.l  (a1)+,(a0)+
                  dbra    d1,cobl
                  movem.l (sp)+,d1/a0-a1
                  rts
*****************
*   VideoInit   *

; THESE ARE THE NTSC DEFINITIONS
ntsc_width      EQU 1409
ntsc_hmid       EQU 823

ntsc_height     EQU 241
ntsc_vmid       EQU 266

; THESE ARE THE PAL DEFINITIONS
pal_width       EQU 1381
pal_hmid        EQU 843

pal_height      EQU 287
pal_vmid        EQU 322

VideoInit:        movem.l d0-d3/a0,-(sp)
                  lea     $00F00000,a0
                  move.w  #322-287,d0      ; vdb
                  move.w  #322+287,d1      ; vde
                  move.w  #(1381+28)>>1-1|$0400,d2 ; hde
                  move.w  #843-(1381+28)>>1+4,d3 ; hdb
                  btst    #4,$00F14003
                  beq.s   VideoInit1       ; =0 => PAL
                  move.w  #266-241,d0
                  move.w  #266+241,d1
                  move.w  #(1409>>1-1)|$0400,d2
                  move.w  #823-(1409>>1)+4,d3
VideoInit1:       move.w  d0,$0046(a0)
;>                  move.w  d1,$0048(a0)
                  move.w #$ffff,$48(a0)
                  move.w  d2,$003C(a0)
                  move.w  d3,$0038(a0)
                  move.w  d3,$003A(a0)
                  move.w  d0,a_vdb(a6)
                  move.w  d1,a_vde(a6)
                  movem.l (sp)+,d0-d3/a0
                  rts
*****************
*    InitOP     *
InitOP:           lea $00F00000,a0
                  moveq #$fe,d0
                  and.w  a_vde(a6),d0
                  or.w #1,d0
                  move.w  d0,$4E(a0)

                  bsr     MakeOBL
                  bsr     CopyOBL

                  lea     ob_list(a6),a1
                  move.l  a1,d0
                  swap    d0
                  move.l  d0,$0020(a0)     ; OPL = $10000
                  move.l  #$1F01<<16,$00E0(a0)
                  lea     my_irq(pc),a0
                  move.l  a0,$00000100.w
                  move    #$2000,sr
                  rts
*****************
*      IRQ      *
my_irq:           movem.l d0-d1,-(sp)
                  btst    #0,$00F000E1
                  beq.s   no_vi
                  bsr CopyOBL
no_vi:            move.l  #$0101<<16,$00F000E0
                  movem.l (sp)+,d0-d1
                  rte
*****************
*********************************************
