
* Init- und Hilfsroutine fr den Bildschirm
* (c) 1994 Bastian Schick
* Basis fr Variablen ist A6
**************************
* Bildschirm (low-level) *
**************************
* Handler fr POL (Pseudo-Objekt-Liste)
*
                  IF 0                     ; noch nicht getestet
                  >PART 'Befehls-Codes'
OBJ_DISABLE       EQU 0
OBJ_ENABLE        EQU 1

OBJ_ADD           EQU $00000010
OBJ_KILL          EQU $00000011
                  ENDPART
                  >PART 'd0=AddPObject(*POL,type,...)'
* AddPseudoObject
* IN : A0  Zeiger auf POL
*      D0  Typ 0..4
*---------------------------------
* Type 0 and Type 1
*      D1.hi/.lo  Xpos/Ypos
*      D2         Height
*      D3.hi/.lo  Pitch/BpP
*      D4.hi/.lo  DWidth/IWidth
*      D5.hi/.lo  FirstPel/Cindex
*      D6         Flags
*      A1         Data
* Type 1 (SBM) only
*      D7.l       Size (xxrrvvhh)
*---------------------------------
* Type 2 (GPU)
*      D1         Ypos
*      D2.l       data.hi
*      D3.l       data.lo
*---------------------------------
* Type 3 (BRANCH)
*      D1         Ypos
*      D2         Condition
*      D3         Link D3>0 => forward
*---------------------------------
* Type 4 (STOP)
*      D1         Interrupt (D1<>0)
*      D2.l       data.hi
*      D3.l       data.lo
*---------------------------------
*---------------------------------
* Out : D0        =0 => Error
*       A0        New POL-Ptr
*---------------------------------
AddPObject:       cmp.w   #4,d0
                  bhi.s   AddPObject4
                  move.w  d0,(a0)+         ; Type Eintragen
                  cmp.w   #1,d0
                  bhi.s   AddPObject1
                  move.w  #obj_bm_len,(a0)
                  subq.w  #1,d0
                  bmi.s   *+4
                  move.w  #obj_sc_len,(a0)
                  addq.l  #2,a0
                  move.l  a1,(a0)+         ; Data
                  move.l  d1,(a0)+         ; Xpos/Ypos
                  move.w  d2,(a0)+         ; Height
                  move.w  #1,(a0)+         ; Link
                  move.b  d3,(a0)+         ; BpP
                  swap    d3
                  move.b  d3,(a0)+         ; Pitch
                  swap    d3
                  move.l  d4,(a0)+         ; Dwidth/Iwidth
                  move.b  d5,(a0)+         ; Cindex
                  move.b  d6,(a0)+         ; Flags
                  swap    d5
                  move.w  d5,(a0)+         ; FirstPel
                  swap    d5
                  tst.w   d0
                  bmi.s   AddPObject0
                  move.l  d7,(a0)+         ; xx;hscale;vscale;rem
AddPObject0:      moveq   #-1,d0
                  rts
AddPObject1:      subq.w  #2,d0            ; GPU ?
                  bne.s   AddPObject2
                  move.w  #obj_gp_len,(a0)+
                  move.w  d1,(a0)+
                  move.w  #1,(a0)+
                  move.l  d2,(a0)+
                  move.l  d3,(a0)+
                  moveq   #-1,d0
                  rts
AddPObject2:      subq.w  #1,d0            ; Branch
                  bne.s   AddPObject3
                  move.w  #obj_br_len,(a0)+
                  movem.w d1-d3,(a0)
                  addq.l  #6,a0
                  move.w  #1,(a0)+
                  moveq   #-1,d0
                  rts
AddPObject3:      move.w  #obj_st_len,(a0)+
                  move.w  d1,(a0)+
                  move.l  d2,(a0)+
                  move.l  d3,(a0)+
                  moveq   #-1,d0
                  rts
AddPObject4:      moveq   #0,d0
                  rts
                  ENDPART
                  ENDC

                  >PART 'struct object'
NEXT_OBJ          EQU 1
***************************************
* BitMap oder Scaled BitMap - Objekte *
***************************************
                  RSRESET
obj_bm_type:      RS.W 1                   ; Type
obj_bm_l:         RS.W 1                   ; Gre des Objektes (fr MakeOBL)
obj_bm_data:      RS.L 1                   ; Data (<0 => rel. zu A6)
obj_bm_x:         RS.W 1                   ; X
obj_bm_y:         RS.W 1                   ; Y pos in Halbzeilen
obj_bm_height:    RS.W 1                   ; Hhe ODER cc bei BRANCH OBJECT
obj_bm_link:      RS.W 1                   ; Abstand zum Nchsten Objekt in Objekten
obj_bm_bits:      RS.B 1                   ; Bits pro Pixel
obj_bm_pitch:     RS.B 1                   ; Pitch
obj_bm_dwidth:    RS.W 1                   ; Breite in Phrases
obj_bm_iwidth:    RS.W 1                   ; Bildbreite (sichtbar)
obj_bm_cindex:    RS.B 1                   ; Farb-Offset
obj_bm_flags:     RS.B 1                   ; Flags
obj_bm_firstpx:   RS.W 1                   ; FirstPixel
obj_bm_len        EQU ^^RSCOUNT
obj_dummy1:       RS.B 1
obj_sc_rem:       RS.B 1
obj_sc_vscale:    RS.B 1
obj_sc_hscale:    RS.B 1                   ; Ergnzungen fr Scaled BitMap
obj_sc_len        EQU ^^RSCOUNT

**************
* GPU-Object *
**************
                  RSRESET
obj_gp_type:      RS.W 1
obj_gp_l:         RS.W 1                   ; Gre des Objektes (fr MakeOBL)
obj_gp_y:         RS.W 1
obj_gp_data1:     RS.L 1
obj_gp_data2:     RS.L 1
obj_gp_link:      RS.W 1

obj_gp_len        EQU ^^RSCOUNT
*****************
* Branch-Object *
*****************
                  RSRESET
obj_br_type:      RS.W 1
obj_br_l:         RS.W 1                   ; Gre des Objektes (fr MakeOBL)
obj_br_y:         RS.W 1
obj_br_cc:        RS.W 1                   ; Bedingung
obj_br_link:      RS.W 2
obj_br_len        EQU ^^RSCOUNT
***************
* Stop-Object *
***************
                  RSRESET
obj_st_type:      RS.W 1
obj_st_l:         RS.W 1
obj_st_int:       RS.W 1
obj_st_data1:     RS.L 1
obj_st_data2:     RS.L 1
obj_st_len        EQU ^^RSCOUNT
                  ENDPART
                  >PART 'MakeOBL'
MakeOBL:          movem.l d0-a4,-(sp)

                  move.l  #$FF000000,d4

                  lea     OBL0(a6),a0
                  lea     OBL(a6),a1
                  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:           move.w  #$03FF,d0
                  and.w   (a2)+,d0
                  lsl.w   #3,d0
                  or.w    d0,d1
                  movem.l (a2)+,d0/d2
                  swap    d2
                  lsr.w   #3,d2
                  and.w   #$E000,d2
                  or.l    d2,d1
                  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)

; BS 28.8.95
;                  moveq   #$7F,d0
;                  and.b   (a2)+,d0
                  move.w  #$00FE,d0
                  and.b   (a2)+,d0
                  lsr.b   #1,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
                  ENDPART
                  >PART 'CopyOBL'
CopyOBL:          movem.l d1/a0,-(sp)
                  lea     OBL(a6),a0
                  lea     OBL0(a6),a1
                  move.w  count_obj(a6),d1
cobl:
                  REPT 8
                  move.l  (a1)+,(a0)+
                  ENDR
                  dbra    d1,cobl
                  movem.l (sp)+,d1/a0
                  rts
                  ENDPART
                  >PART 'Objekte'
Objekte:
*0
                  DC.W $AFFE               ; generates STOPOBJ

                  ENDPART
                  >PART 'videoinit'
*****************
*   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  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
*****************
                  ENDPART
                  >PART 'InitOP'
InitOP:           lea     $00F00000,a0
                  move.w  a_vde(a6),d0
                  addq.w  #2,d0
                  move.w  d0,$004E(a0)

                  bsr     MakeOBL
                  bsr     CopyOBL

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

OBL:              RS.B 10*32
OBL0:             RS.B 10*32
count_obj:        RS.W 1
a_vdb:            RS.W 1
a_vde:            RS.W 1
                  END
