; Atari display module.  Procedure Handle_TIA is called every time the
; screen registers are changed.

VSYNC   EQU   0
VBLANK  EQU   1
WSYNC   EQU   2
RSYNC   EQU   3
NUSIZ0  EQU   4
NUSIZ1  EQU   5
COLUP0  EQU   6
COLUP1  EQU   7
COLUPF  EQU   8
COLUBK  EQU   9
CTRLPF  EQU   0Ah
REFP0   EQU   0Bh
REFP1   EQU   0Ch
PF0     EQU   0Dh
PF1     EQU   0Eh
PF2     EQU   0Fh
RESP0   EQU   10h
RESP1   EQU   11h
RESM0   EQU   12h
RESM1   EQU   13h
RESBL   EQU   14h
GRP0    EQU   1Bh
GRP1    EQU   1Ch
ENAM0   EQU   1Dh
ENAM1   EQU   1Eh
ENABL   EQU   1Fh
HMP0    EQU   20h
HMP1    EQU   21h
HMM0    EQU   22h
HMM1    EQU   23h
HMBL    EQU   24h
VDELP0  EQU   25h
VDELP1  EQU   26h
VDELBL  EQU   27h
RESMP0  EQU   28h
RESMP1  EQU   29h
HMOVE   EQU   2Ah
HMCLR   EQU   2Bh
CXCLR   EQU   2Ch
SWCHA1  EQU   280h
SWACNT1 EQU   281h
SWCHB1  EQU   282h
SWBCNT1 EQU   283h
INTTIM1 EQU   284h
TIM1T1  EQU   294h
TIM2T1  EQU   295h
TIM3T1  EQU   296h
TIM4T1  EQU   297h
SWCHA2  EQU   380h
SWACNT2 EQU   381h
SWCHB2  EQU   382h
SWBCNT2 EQU   383h
INTTIM2 EQU   384h
TIM1T2  EQU   394h
TIM2T2  EQU   395h
TIM3T2  EQU   396h
TIM4T2  EQU   397h

.486
.MODEL FLAT

Player0Set  EQU 2
Player1Set  EQU 4
Missile0Set EQU 8
Missile1Set EQU 16
BallSet     EQU 32

P0CBase EQU   07D8Fh
P1CBase EQU   08D7Fh
M0CBase EQU   0FE33h
M1CBase EQU   032FFh
PFCBase EQU   0D7D5h
BLCBase EQU   0EBE9h  ; was EBEBh

TIA_RegList struc
    DB     40h dup (?)
ends

LatchQueueSize EQU 16

TSave struc
    TIA_Regs                       DB 40h dup (?)
    TIA_Count                      DW ?
    Old_TIA_Count                  DW ?
    TIA_Scan                       DW ?
    ObjectLoc                      DD 17 dup (?)
    ObjectPix                      DD 17 dup (?)
    Player0Size                    DD ?
    Player1Size                    DD ?
    Player0Size160                 DD ?
    Player1Size160                 DD ?
    Player0Size128                 DD ?
    Player1Size128                 DD ?
    Missile0Size                   DD ?
    Missile1Size                   DD ?
    Missile0Size160                DD ?
    Missile1Size160                DD ?
    Missile0SizeNum                DD ?
    Missile1SizeNum                DD ?
    Addr                           DD ?
    ColorLum                       DW 4 dup (?)
    BallSize                       DD ?
    BallSize160                    DD ?
    CLW                            DD ?
    CRW                            DD ?
    Input_Byte                     DB 16 dup (?)
    DispJump                       DD ?
    DoHMOVE                        DB ?
    LineStart                      DW ?
    LastScan                       DD ?
    NewScan                        DD ?
    TopVBLANK                      DB ?
    TIA_Latch_Value                DW LatchQueueSize dup (?)
    TIA_Latch_Reg                  DB LatchQueueSize dup (?)
    TIA_Latch_Count                DW LatchQueueSize dup (?)
    TIA_Latch_Scan                 DW LatchQueueSize dup (?)
    TIA_Latch_Queue                DW ?
    TIA_Latch_RegCount             DW 2Dh dup (?)
    MaxRows                        DW ?
    Missile0Wrap                   DD ?
    Missile1Wrap                   DD ?
ends

.DATA

        extrn Game                : TSave

        extrn MissileTable        : byte
        extrn BitSwap             : byte
        extrn Limit               : byte
        extrn ByteShift           : byte
        extrn BitTest             : byte
        extrn Handle_TIA_Jump     : byte
        extrn Handle_TIA_Jump_Set : byte
        extrn AtariSeg            : byte
        extrn TIA_Latch_Check     : byte
        extrn Config              : byte

        extrn Handle_IO_Latch_Ptr : byte

        extrn ScnPtr              : byte

.CODE

public Handle_TIA

; -------------------------------------------------------------------------
; Display player 0 and missile 0 for 160x200 mode
; -------------------------------------------------------------------------
_P0M0_160   macro
        local Show0,GetOut1,ShowM0,GetOut3,GetOut3a,Show1,Show1a
        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Player0Set * 2]
        CMP   EBX,DWORD PTR Game.Player0Size
        JA    SHORT GetOut1
        JNZ   SHORT Show0
        ADD   DWORD PTR Game.ObjectPix[Player0Set * 2],160
Show0:
        ADD   EBX,DWORD PTR Game.Player0Size128
        MOV   DL,BYTE PTR ByteShift[EBX]
        TEST  DL,BYTE PTR Game.TIA_Regs[GRP0]
        JZ    SHORT GetOut1
        MOV   BL,BYTE PTR Game.ColorLum[0]
        MOV   BYTE PTR [EDI],BL

  ; Display missile 0

        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Missile0Set * 2]
        CMP   EBX,DWORD PTR Game.Player0Size
        JA    SHORT GetOut3
        JNZ   SHORT Show1
        MOV   EDX,DWORD PTR Game.Missile0Wrap
        ADD   DWORD PTR Game.ObjectPix[Missile0Set * 2],EDX
        DEC   DH
Show1:
        ADD   EBX,DWORD PTR Game.Missile0SizeNum
        TEST  BYTE PTR MissileTable[EBX],DH ; 0FFh
        JZ    SHORT GetOut3
        JMP   SHORT GetOut3a
GetOut1:
        AND   ESI,P0CBase

  ; Display missile 0

        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Missile0Set * 2]
        CMP   EBX,DWORD PTR Game.Player0Size
        JA    SHORT GetOut3
        JNZ   SHORT Show1a
        MOV   EDX,DWORD PTR Game.Missile0Wrap
        ADD   DWORD PTR Game.ObjectPix[Missile0Set * 2],EDX
        DEC   DH
Show1a:
        ADD   EBX,DWORD PTR Game.Missile0SizeNum
        TEST  BYTE PTR MissileTable[EBX],DH ; 0FFh
        JZ    SHORT GetOut3
        MOV   BL,BYTE PTR Game.ColorLum[0]
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut3a
GetOut3:
        AND   ESI,M0CBase
GetOut3a:
        endm


; -------------------------------------------------------------------------
; Display player 0 for 160x200 mode
; -------------------------------------------------------------------------
_P0_160  macro
        local Show0,GetOut1,GetOut3a
        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Player0Set * 2]
        CMP   EBX,DWORD PTR Game.Player0Size
        JA    SHORT GetOut1
        JNZ   SHORT Show0
        ADD   DWORD PTR Game.ObjectPix[Player0Set * 2],160
Show0:
        ADD   EBX,DWORD PTR Game.Player0Size128
        MOV   DL,BYTE PTR ByteShift[EBX]
        TEST  DL,BYTE PTR Game.TIA_Regs[GRP0]
        JZ    SHORT GetOut1
        MOV   BL,BYTE PTR Game.ColorLum[0]
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut3a
GetOut1:
        AND   ESI,P0CBase
GetOut3a:
        endm


; -------------------------------------------------------------------------
; Display missile 0 for 160x200 mode
; -------------------------------------------------------------------------
_M0_160  macro
        local ShowM0,GetOut3,GetOut3a,Show1

        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Missile0Set * 2]
        CMP   EBX,DWORD PTR Game.Player0Size
        JA    SHORT GetOut3
        JNZ   SHORT Show1
        MOV   EDX,DWORD PTR Game.Missile0Wrap
        ADD   DWORD PTR Game.ObjectPix[Missile0Set * 2],EDX
        DEC   DH
Show1:
        ADD   EBX,DWORD PTR Game.Missile0SizeNum
        TEST  BYTE PTR MissileTable[EBX],DH ; 0FFh
        JZ    SHORT GetOut3
        MOV   BL,BYTE PTR Game.ColorLum[0]
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut3a
GetOut3:
        AND   ESI,M0CBase
GetOut3a:
        endm


; -------------------------------------------------------------------------
; Display player 1 and missile 1 for 160x200 mode
; -------------------------------------------------------------------------
_P1M1_160   macro
        local Show1,GetOut2,ShowM1,GetOut4,GetOut4a,Show2,Show2a
        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Player1Set * 2]
        CMP   EBX,DWORD PTR Game.Player1Size
        JA    SHORT GetOut2
        JNZ   SHORT Show1
        ADD   DWORD PTR Game.ObjectPix[Player1Set * 2],160
Show1:
        ADD   EBX,DWORD PTR Game.Player1Size128
        MOV   DL,BYTE PTR ByteShift[EBX]
        TEST  DL,BYTE PTR Game.TIA_Regs[GRP1]
        JZ    SHORT GetOut2
        MOV   BL,BYTE PTR Game.ColorLum[2]
        MOV   BYTE PTR [EDI],BL

  ; Display missile 1

        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Missile1Set * 2]
        CMP   EBX,DWORD PTR Game.Player1Size
        JA    SHORT GetOut4
        JNZ   SHORT Show2
        MOV   EDX,DWORD PTR Game.Missile1Wrap
        ADD   DWORD PTR Game.ObjectPix[Missile1Set * 2],EDX
        DEC   DH
Show2:
        ADD   EBX,DWORD PTR Game.Missile1SizeNum
        TEST  BYTE PTR MissileTable[EBX],DH ; 0FFh
        JZ    SHORT GetOut4
        JMP   SHORT GetOut4a
GetOut2:
        AND   ESI,P1CBase

  ; Display missile 1

        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Missile1Set * 2]
        CMP   EBX,DWORD PTR Game.Player1Size
        JA    SHORT GetOut4
        JNZ   SHORT Show2a
        MOV   EDX,DWORD PTR Game.Missile1Wrap
        ADD   DWORD PTR Game.ObjectPix[Missile1Set * 2],EDX
        DEC   DH
Show2a:
        ADD   EBX,DWORD PTR Game.Missile1SizeNum
        TEST  BYTE PTR MissileTable[EBX],DH ; 0FFh
        JZ    SHORT GetOut4
        MOV   BL,BYTE PTR Game.ColorLum[2]
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut4a
GetOut4:
        AND   ESI,M1CBase
GetOut4a:
        endm


; -------------------------------------------------------------------------
; Display player 1 for 160x200 mode
; -------------------------------------------------------------------------
_P1_160  macro
        local Show1,GetOut2,GetOut4a
        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Player1Set * 2]
        CMP   EBX,DWORD PTR Game.Player1Size
        JA    SHORT GetOut2
        JNZ   SHORT Show1
        ADD   DWORD PTR Game.ObjectPix[Player1Set * 2],160
Show1:
        ADD   EBX,DWORD PTR Game.Player1Size128
        MOV   DL,BYTE PTR ByteShift[EBX]
        TEST  DL,BYTE PTR Game.TIA_Regs[GRP1]
        JZ    SHORT GetOut2
        MOV   BL,BYTE PTR Game.ColorLum[2]
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut4a
GetOut2:
        AND   ESI,P1CBase
GetOut4a:
        endm


; -------------------------------------------------------------------------
; Display missile 1 for 160x200 mode
; -------------------------------------------------------------------------
_M1_160  macro
        local ShowM1,GetOut4,GetOut4a,Show2a

        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectPix[Missile1Set * 2]
        CMP   EBX,DWORD PTR Game.Player1Size
        JA    SHORT GetOut4
        JNZ   SHORT Show2a
        MOV   EDX,DWORD PTR Game.Missile1Wrap
        ADD   DWORD PTR Game.ObjectPix[Missile1Set * 2],EDX
        DEC   DH
Show2a:
        ADD   EBX,DWORD PTR Game.Missile1SizeNum
        TEST  BYTE PTR MissileTable[EBX],DH ; 0FFh
        JZ    SHORT GetOut4
        MOV   BL,BYTE PTR Game.ColorLum[2]
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut4a
GetOut4:
        AND   ESI,M1CBase
GetOut4a:
        endm


; -------------------------------------------------------------------------
; Display ball for 160x200 mode
; -------------------------------------------------------------------------
_BL_160  macro
        local ShowBL,GetOut5,GetOut5a
        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectLoc[BallSet * 2]
        CMP   EBX,DWORD PTR Game.BallSize
        JB    SHORT ShowBL
        CMP   EBX,DWORD PTR Game.BallSize160
        JGE   SHORT GetOut5
ShowBL:
        MOV   BL,BYTE PTR Game.ColorLum[4]
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut5a
GetOut5:
        AND   ESI,BLCBase
GetOut5a:
        endm


; -------------------------------------------------------------------------
; Display ball for 160x200 mode
; -------------------------------------------------------------------------
_BL_1601st  macro
        local ShowBL,GetOut5,GetOut5a
        MOV   EBX,EAX
        SUB   EBX,DWORD PTR Game.ObjectLoc[BallSet * 2]
        CMP   EBX,DWORD PTR Game.BallSize
        JB    SHORT ShowBL
        CMP   EBX,DWORD PTR Game.BallSize160
        JGE   SHORT GetOut5
ShowBL:
        MOV   BL,BYTE PTR Game.ColorLum[4]
        JMP   SHORT GetOut5a
GetOut5:
        MOV   BL,BYTE PTR Game.ColorLum[6]
        AND   ESI,BLCBase
GetOut5a:
        MOV   BYTE PTR [EDI],BL
        endm


; -------------------------------------------------------------------------
; Display playfield before anything else for 160x200 mode
; -------------------------------------------------------------------------
_PF1st_160  macro
        local L1,L2,GetOut
        MOV   EBX,EAX
        MOV   BH,BYTE PTR Game.TIA_Regs[CTRLPF]
        AND   EBX,01FCh
        TEST  ECX,DWORD PTR BitTest[EBX]
        JZ    SHORT L2
        CMP   EAX,80
        JAE   SHORT L1
        MOV   BL,BYTE PTR Game.CLW
        JMP   SHORT GetOut
L1:
        MOV   BL,BYTE PTR Game.CRW
        JMP   SHORT GetOut
L2:
        MOV   BL,BYTE PTR Game.ColorLum[6]
        AND   ESI,PFCBase
GetOut:
        MOV   BYTE PTR [EDI],BL
        endm


; -------------------------------------------------------------------------
; Display playfield after everything else for 160x200 mode
; -------------------------------------------------------------------------
_PFlast_160 macro
        local L1,L2,GetOut
        MOV   EBX,EAX
        MOV   BH,BYTE PTR Game.TIA_Regs[CTRLPF]
        AND   EBX,01FCh
        TEST  ECX,DWORD PTR BitTest[EBX]
        JZ    SHORT L2
        CMP   EAX,80
        JAE   SHORT L1
        MOV   BL,BYTE PTR Game.CLW
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut
L1:
        MOV   BL,BYTE PTR Game.CRW
        MOV   BYTE PTR [EDI],BL
        JMP   SHORT GetOut
L2:
        AND   ESI,PFCBase
GetOut:
        endm


; -------------------------------------------------------------------------
; Display loop for 160x200 mode
; -------------------------------------------------------------------------
_Disp160   macro Collision,P0,M0,P1,M1,Ball
        local Top1,Top
        TEST  BYTE PTR Game.TIA_Regs[CTRLPF],4
        JZ    Top
Top1:
        MOV   ESI,Collision                   ; Set up collision counter
        MOV   BL,BYTE PTR Game.ColorLum[6]    ; Default: background color
        MOV   BYTE PTR [EDI],BL
        if P1 ne 0
          if M1 ne 0
          _P1M1_160
          else
          _P1_160
          endif
        else
          if M1 ne 0
          _M1_160
          endif
        endif
        if P0 ne 0
          if M0 ne 0
          _P0M0_160
          else
          _P0_160
          endif
        else
          if M0 ne 0
          _M0_160
          endif
        endif
        _PFlast_160
        if Ball ne 0
        _BL_160
        endif
        INC   EDI                             ; Write pixel and move on
        OR    EBP,ESI                         ; Tally collisions
        INC   EAX                             ; Next pixel
        CMP   EAX,DWORD PTR Limit
        JB    Top1
        JMP   @Exiting
Top:
        MOV   ESI,Collision                   ; Set up collision counter
        _PF1st_160
        if Ball ne 0
        _BL_160
        endif
        if P1 ne 0
          if M1 ne 0
          _P1M1_160
          else
          _P1_160
          endif
        else
          if M1 ne 0
          _M1_160
          endif
        endif
        if P0 ne 0
          if M0 ne 0
          _P0M0_160
          else
          _P0_160
          endif
        else
          if M0 ne 0
          _M0_160
          endif
        endif
        INC   EDI                             ; Write pixel and move on
        OR    EBP,ESI                         ; Tally collisions
        INC   EAX                             ; Next pixel
        CMP   EAX,DWORD PTR Limit
        JB    Top
        endm

; -------------------------------------------------------------------------
; Display loop, used for playfield only for 160x200 mode
; -------------------------------------------------------------------------
_DispNothingLoop160 macro
        local L1,L1A,L2A,NoPix,Outside,Leaving,Lt1,Lt2,Lt3,Lt1No
        local Lt2No,Lt3No,Outside1,Lt0,Lt0No,LeftOver,LeftOver1
        local L3,L3A

        SUB   AH,AL

        MOV   BL,AL
        AND   EBX,01FCh
        TEST  ESI,DWORD PTR BitTest[EBX]
        JZ    SHORT NoPix

        AND   AL,3                ; Playfield is displayed
        JNZ   SHORT L1
        MOV   AL,AH
        AND   AH,3
        SHR   AL,2
        JNZ   SHORT Outside1
        JMP   SHORT Lt0
L1:
        CMP   AL,1
        JZ    SHORT Lt1
        CMP   AL,2
        JZ    SHORT Lt2
        JMP   SHORT Lt3
NoPix:
        AND   AL,3                ; Background is displayed
        JNZ   SHORT L1A
        MOV   AL,AH
        AND   AH,3
        SHR   AL,2
        JNZ   L2A
        JMP   Lt0No
L1A:
        CMP   AL,1
        JZ    Lt1No
        CMP   AL,2
        JZ    Lt2No
        JMP   Lt3No
Outside:
        TEST  ESI,DWORD PTR BitTest[EBX]
        JZ    SHORT L2A
Outside1:
        MOV   DWORD PTR [EDI],EDX
        ADD   EBX,4
        ADD   EDI,4
        DEC   AL
        JNZ   SHORT Outside
        TEST  AH,AH
        JZ    Leaving
LeftOver:
        TEST  ESI,DWORD PTR BitTest[EBX]
        JZ    SHORT Lt0No
Lt0:
        MOV   BYTE PTR [EDI],DL
        INC   EDI                             ; Write pixel and move on
        DEC   AH
        JZ    Leaving
Lt1:
        MOV   BYTE PTR [EDI],DL
        INC   EDI                             ; Write pixel and move on
        DEC   AH
        JZ    Leaving
Lt2:
        MOV   BYTE PTR [EDI],DL
        INC   EDI                             ; Write pixel and move on
        DEC   AH
        JZ    SHORT Leaving
Lt3:
        MOV   BYTE PTR [EDI],DL
        INC   EDI                             ; Write pixel and move on
        ADD   EBX,4
        DEC   AH
        TEST  AH,0FCh
        JZ    SHORT L3
        MOV   AL,AH
        SHR   AL,2
        AND   AH,3
        JMP   SHORT Outside
L3:
        TEST  AH,AH
        JNZ   SHORT LeftOver
        JMP   Leaving

L2A:
        MOV   DWORD PTR [EDI],ECX
        ADD   EBX,4
        ADD   EDI,4
        DEC   AL
        JNZ   SHORT Outside
        TEST  AH,AH
        JZ    SHORT Leaving
LeftOver1:
        TEST  ESI,DWORD PTR BitTest[EBX]
        JNZ   SHORT Lt0
Lt0No:
        MOV   BYTE PTR [EDI],CL
        INC   EDI                             ; Write pixel and move on
        DEC   AH
        JZ    SHORT Leaving
Lt1No:
        MOV   BYTE PTR [EDI],CL
        INC   EDI                             ; Write pixel and move on
        DEC   AH
        JZ    SHORT Leaving
Lt2No:
        MOV   BYTE PTR [EDI],CL
        INC   EDI                             ; Write pixel and move on
        DEC   AH
        JZ    SHORT Leaving
Lt3No:
        MOV   BYTE PTR [EDI],CL
        INC   EDI                             ; Write pixel and move on
        ADD   EBX,4
        DEC   AH
        TEST  AH,0FCh
        JZ    SHORT L3A
        MOV   AL,AH
        SHR   AL,2
        AND   AH,3
        JMP   Outside
L3A:
        TEST  AH,AH
        JNZ   SHORT LeftOver1
Leaving:
        OR    EBP,1
        endm


; -------------------------------------------------------------------------
; Display loop -- special case; playfield only for 160x200 mode
; -------------------------------------------------------------------------
_DispNothing160  macro
        local Top1,L1
        MOV   BH,BYTE PTR Game.TIA_Regs[CTRLPF]
        MOV   AH,BYTE PTR Limit

        MOV   ESI,DWORD PTR Game.ColorLum[4]
        MOV   SI,WORD PTR Game.ColorLum[6]

        XCHG  ESI,ECX
        CMP   AL,80
        JAE   Top1
        MOV   EDX,DWORD PTR Game.CLW
        PUSH  EAX
        CMP   AH,80
        JBE   L1
        MOV   AH,80
L1:
        _DispNothingLoop160
        POP   EAX
        CMP   AH,80
        JBE   @Exiting
        MOV   AL,80
Top1:
        MOV   EDX,DWORD PTR Game.CRW
        _DispNothingLoop160
        endm


; -------------------------------------------------------------------------
; Display loop -- special case; playfield only (left side) for 160x200 mode
; -------------------------------------------------------------------------
_DispLeftNothing160  macro
        MOV   BH,BYTE PTR Game.TIA_Regs[CTRLPF]
        MOV   AH,BYTE PTR Limit

        MOV   ESI,DWORD PTR Game.ColorLum[4]
        MOV   SI,WORD PTR Game.ColorLum[6]
        XCHG  ESI,ECX
        MOV   EDX,DWORD PTR Game.CLW
        _DispNothingLoop160
        endm


; -------------------------------------------------------------------------
; Display loop -- special case; playfield only (right side) for 160x200 mode
; -------------------------------------------------------------------------
_DispRightNothing160  macro
        MOV   BH,BYTE PTR Game.TIA_Regs[CTRLPF]
        MOV   AH,BYTE PTR Limit

        MOV   ESI,DWORD PTR Game.ColorLum[4]
        MOV   SI,WORD PTR Game.ColorLum[6]
        XCHG  ECX,ESI
        MOV   EDX,DWORD PTR Game.CRW
        _DispNothingLoop160
        endm


; -------------------------------------------------------------------------

Handle_TIA proc

  ; We're going to use EBP as a general-purpose register; there MUST NOT
  ; be any local variables!!!

  ; Save registers

        PUSHAD

  ; Set up collision total

        SUB   EBP,EBP

; ----------------------------------

  ; Check latched TIA register write delay

        TEST  BYTE PTR TIA_Latch_Check,0FFh
        JZ    @DontCheckLatches

        MOV   SI,WORD PTR Game.TIA_Latch_Queue
        TEST  SI,SI
        JZ    @DontCheckLatches   ; Jump if nothing in the queue

        SUB   ESI,ESI

@LatchLoop:

        MOV   EDI,ESI
        ADD   EDI,EDI

        MOVSX EAX,WORD PTR Game.TIA_Scan
        CMP   AX,WORD PTR Game.TIA_Latch_Scan[EDI]
        JG    @NewLatchedReg
        JL    @NoLatchChange

        MOVSX EAX,WORD PTR Game.TIA_Count
        MOVSX EBX,WORD PTR Game.TIA_Latch_Count[EDI]
        CMP   EAX,EBX
        JLE   @NoLatchChange

        ; Break up into two runs; pre-change and post-change

        PUSH  WORD PTR Game.TIA_Count
        MOV   WORD PTR Game.TIA_Count,BX
        MOV   BYTE PTR TIA_Latch_Check,0
        PUSH  ESI
        PUSH  EDI
        CALL  Handle_TIA
        POP   EDI
        POP   ESI
        POP   WORD PTR Game.TIA_Count
        MOV   BYTE PTR TIA_Latch_Check,1

        ; Recall collisions from previous run

        MOV   EAX,DWORD PTR Game.Input_Byte[6]
        AND   EAX,0C080h
        MOV   EBP,EAX
        SHR   EBP,2
        MOV   EAX,DWORD PTR Game.Input_Byte[4]
        AND   EAX,0C0C0h
        OR    EBP,EAX
        SHR   EBP,2
        MOV   EAX,DWORD PTR Game.Input_Byte[2]
        AND   EAX,0C0C0h
        OR    EBP,EAX
        SHR   EBP,2
        MOV   EAX,DWORD PTR Game.Input_Byte[0]
        AND   EAX,0C0C0h
        OR    EBP,EAX

@NewLatchedReg:

        ; Copy the new value from the latch into registers

        MOVZX EBX,BYTE PTR Game.TIA_Latch_Reg[ESI]
        MOVZX EDX,WORD PTR Game.TIA_Latch_Value[EDI]
        MOV   BYTE PTR AtariSeg[EBX],DL
        MOV   BYTE PTR Game.TIA_Regs[EBX],DL
        DEC   BYTE PTR Game.TIA_Latch_RegCount[EBX]

        ; Get rid of this latch, copying higher ones down

        PUSH  ESI
        MOV   AX,WORD PTR Game.TIA_Latch_Queue
        DEC   AX
@LatchCopyLoop:
        CMP   SI,AX
        JGE   SHORT @DoneCopyingLatches
        MOV   CL,BYTE PTR Game.TIA_Latch_Reg[ESI + 1]
        MOV   BYTE PTR Game.TIA_Latch_Reg[ESI],CL
        MOV   CX,WORD PTR Game.TIA_Latch_Value[EDI + 2]
        MOV   WORD PTR Game.TIA_Latch_Value[EDI],CX
        MOV   CX,WORD PTR Game.TIA_Latch_Scan[EDI + 2]
        MOV   WORD PTR Game.TIA_Latch_Scan[EDI],CX
        MOV   CX,WORD PTR Game.TIA_Latch_Count[EDI + 2]
        MOV   WORD PTR Game.TIA_Latch_Count[EDI],CX
        INC   ESI
        ADD   EDI,2
        JMP   SHORT @LatchCopyLoop
@DoneCopyingLatches:
        POP   ESI

        DEC   WORD PTR Game.TIA_Latch_Queue

        ; Act on the new register's value (EBX and EDX are already set)

        PUSHAD
        CALL  DWORD PTR Handle_IO_Latch_Ptr
        POPAD

        DEC   ESI

@NoLatchChange:

        INC   ESI
        CMP   SI,WORD PTR Game.TIA_Latch_Queue
        JB    @LatchLoop

;        TEST  SI,SI
;        JNZ   @LatchLoop

@DontCheckLatches:

; ----------------------------------

  ; If we're in the vertical blanking area, exit.

        TEST  BYTE PTR Game.TIA_Regs[VBLANK],2
        JZ    SHORT @TestOk1

        MOVSX EAX,WORD PTR Game.TIA_Scan
        CMP   EAX,DWORD PTR Game.NewScan
        JGE   SHORT @ExitP1
        JMP   SHORT @TestOk1
@ExitP1:
        MOV   EAX,DWORD PTR Game.LastScan
        MOV   DWORD PTR Game.NewScan,EAX
        JMP   @ExitP
@TestOk1:

  ; If Old_TIA_Count is greater or equal to TIA_Count, exit.

        MOVSX EAX,WORD PTR Game.TIA_Count
        CMP   AX,WORD PTR Game.Old_TIA_Count
        JG    SHORT @TestOk2
        JMP   @ExitP
@TestOk2:

  ; If TIA_Count is negative, exit.

        TEST  EAX,EAX
        JNS   SHORT @TestOk3
        JMP   @ExitP
@TestOk3:

  ; If we have gone past the last scan line, exit.

        MOV   AX,WORD PTR Game.MaxRows
        CMP   WORD PTR Game.TIA_Scan,AX
        JAE   @ExitP

; ----------------------------------

  ; Fill the jump table if it hasn't been filled yet

        TEST  BYTE PTR Handle_TIA_Jump_Set,0FFh
        JNZ   @JumpTableSet

        MOV   DWORD PTR Handle_TIA_Jump[00h * 4],OFFSET DoNothing160
        MOV   DWORD PTR Handle_TIA_Jump[01h * 4],OFFSET DoBL160
        MOV   DWORD PTR Handle_TIA_Jump[02h * 4],OFFSET DoM1160
        MOV   DWORD PTR Handle_TIA_Jump[03h * 4],OFFSET DoM1BL160
        MOV   DWORD PTR Handle_TIA_Jump[04h * 4],OFFSET DoP1160
        MOV   DWORD PTR Handle_TIA_Jump[05h * 4],OFFSET DoP1BL160
        MOV   DWORD PTR Handle_TIA_Jump[06h * 4],OFFSET DoM1P1160
        MOV   DWORD PTR Handle_TIA_Jump[07h * 4],OFFSET DoM1P1BL160
        MOV   DWORD PTR Handle_TIA_Jump[08h * 4],OFFSET DoM0160
        MOV   DWORD PTR Handle_TIA_Jump[09h * 4],OFFSET DoM0BL160
        MOV   DWORD PTR Handle_TIA_Jump[0Ah * 4],OFFSET DoM0M1160
        MOV   DWORD PTR Handle_TIA_Jump[0Bh * 4],OFFSET DoM0M1BL160
        MOV   DWORD PTR Handle_TIA_Jump[0Ch * 4],OFFSET DoM0P1160
        MOV   DWORD PTR Handle_TIA_Jump[0Dh * 4],OFFSET DoM0P1BL160
        MOV   DWORD PTR Handle_TIA_Jump[0Eh * 4],OFFSET DoM0P1M1160
        MOV   DWORD PTR Handle_TIA_Jump[0Fh * 4],OFFSET DoM0P1M1BL160
        MOV   DWORD PTR Handle_TIA_Jump[10h * 4],OFFSET DoP0160
        MOV   DWORD PTR Handle_TIA_Jump[11h * 4],OFFSET DoP0BL160
        MOV   DWORD PTR Handle_TIA_Jump[12h * 4],OFFSET DoP0M1160
        MOV   DWORD PTR Handle_TIA_Jump[13h * 4],OFFSET DoP0M1BL160
        MOV   DWORD PTR Handle_TIA_Jump[14h * 4],OFFSET DoP0P1160
        MOV   DWORD PTR Handle_TIA_Jump[15h * 4],OFFSET DoP0P1BL160
        MOV   DWORD PTR Handle_TIA_Jump[16h * 4],OFFSET DoP0P1M1160
        MOV   DWORD PTR Handle_TIA_Jump[17h * 4],OFFSET DoP0P1M1BL160
        MOV   DWORD PTR Handle_TIA_Jump[18h * 4],OFFSET DoP0M0160
        MOV   DWORD PTR Handle_TIA_Jump[19h * 4],OFFSET DoP0M0BL160
        MOV   DWORD PTR Handle_TIA_Jump[1Ah * 4],OFFSET DoP0M0M1160
        MOV   DWORD PTR Handle_TIA_Jump[1Bh * 4],OFFSET DoP0M0M1BL160
        MOV   DWORD PTR Handle_TIA_Jump[1Ch * 4],OFFSET DoP0M0P1160
        MOV   DWORD PTR Handle_TIA_Jump[1Dh * 4],OFFSET DoP0M0P1BL160
        MOV   DWORD PTR Handle_TIA_Jump[1Eh * 4],OFFSET DoP0M0P1M1160
        MOV   DWORD PTR Handle_TIA_Jump[1Fh * 4],OFFSET DoP0M0P1M1BL160
        MOV   BYTE PTR Handle_TIA_Jump_Set,1
@JumpTableSet:

; ----------------------------------

  ; Check for wraparound

        MOVSX ECX,WORD PTR Game.Old_TIA_Count
        TEST  ECX,ECX
        JNS   SHORT @Positive
        SUB   ECX,ECX
@Positive:
        TEST  BYTE PTR Game.DoHMOVE,1
        JZ    SHORT @HMOVEOkA
        CMP   ECX,8
        JAE   SHORT @HMOVEOkA
        MOV   ECX,8
@HMOVEOkA:

  ; Player 0

        MOV   EAX,DWORD PTR Game.ObjectLoc[Player0Set * 2]
        MOV   EBX,EAX
        ADD   EBX,DWORD PTR Game.Player0Size160
        JLE   SHORT @P0NotOk
        CMP   EBX,ECX ; WORD PTR Game.Old_TIA_Count
        JL    SHORT @P0NotOk
        SUB   EAX,160
@P0NotOk:
        MOV   DWORD PTR Game.ObjectPix[Player0Set * 2],EAX
        CMP   BYTE PTR Game.Player0Size,15
        JE    @P0Double
        CMP   BYTE PTR Game.Player0Size,31
        JNE   @NoP0Add
@P0Double:
        INC   DWORD PTR Game.ObjectPix[Player0Set * 2]
@NoP0Add:

  ; Player 1

        MOV   EAX,DWORD PTR Game.ObjectLoc[Player1Set * 2]
        MOV   EBX,EAX
        ADD   EBX,DWORD PTR Game.Player1Size160
        JLE   SHORT @P1NotOk
        CMP   EBX,ECX ; WORD PTR Game.Old_TIA_Count
        JL    SHORT @P1NotOk
        SUB   EAX,160
@P1NotOk:
        MOV   DWORD PTR Game.ObjectPix[Player1Set * 2],EAX
        CMP   BYTE PTR Game.Player1Size,15
        JE    @P1Double
        CMP   BYTE PTR Game.Player1Size,31
        JNE   @NoP1Add
@P1Double:
        INC   DWORD PTR Game.ObjectPix[Player1Set * 2]
@NoP1Add:

  ; Missile 0

        MOV   DWORD PTR Game.Missile0Wrap,0
        MOV   EAX,DWORD PTR Game.ObjectLoc[Missile0Set * 2]
        MOV   EBX,EAX
        ADD   EBX,DWORD PTR Game.Player0Size160
        JLE   SHORT @M0NotOk
        CMP   EBX,ECX ; WORD PTR Game.Old_TIA_Count
        JL    SHORT @M0NotOk
        SUB   EAX,160
        MOV   DWORD PTR Game.Missile0Wrap,160
@M0NotOk:
        MOV   DWORD PTR Game.ObjectPix[Missile0Set * 2],EAX

  ; Missile 1

        MOV   DWORD PTR Game.Missile1Wrap,0
        MOV   EAX,DWORD PTR Game.ObjectLoc[Missile1Set * 2]
        MOV   EBX,EAX
        ADD   EBX,DWORD PTR Game.Player1Size160
        JLE   SHORT @M1NotOk
        CMP   EBX,ECX ; WORD PTR Game.Old_TIA_Count
        JL    SHORT @M1NotOk
        SUB   EAX,160
        MOV   DWORD PTR Game.Missile1Wrap,160
@M1NotOk:
        MOV   DWORD PTR Game.ObjectPix[Missile1Set * 2],EAX

  ; Set up playfield data

        SUB   EBX,EBX
        MOV   BL,BYTE PTR Game.TIA_Regs[PF0]
        MOV   CH,BYTE PTR BitSwap[EBX]
        BSWAP ECX
        MOV   CH,BYTE PTR Game.TIA_Regs[PF1]
        MOV   BL,BYTE PTR Game.TIA_Regs[PF2]
        MOV   CL,BYTE PTR BitSwap[EBX]

  ; Set up pointer to screen

        MOV   EDI,DWORD PTR Game.Addr
        ADD   EDI,DWORD PTR ScnPtr

  ; Set starting position

        MOVSX EAX,WORD PTR Game.Old_TIA_Count
        TEST  EAX,EAX
        JNS   SHORT @StartOk
        SUB   EAX,EAX
@StartOk:

  ; Loop across screen from Game.Old_TIA_Count to Game.TIA_Count - 1 or 159

        MOV   AH,BYTE PTR Game.TIA_Count
        CMP   AH,160
        JBE   SHORT @AHOk
        MOV   AH,160
@AHOk:

  ; See if the first 8 pixels need to be blanked out

        TEST  BYTE PTR Game.DoHMOVE,1
        JZ    @HMOVEOk
        CMP   AL,8
        JAE   @HMOVEOk



        PUSH  WORD PTR TIA_Latch_Check
        MOV   BYTE PTR TIA_Latch_Check,0
        PUSH  DWORD PTR Game.ColorLum[0]
        PUSH  DWORD PTR Game.ColorLum[4]
        PUSH  DWORD PTR Game.CLW
        PUSH  DWORD PTR Game.CRW
        MOV   DWORD PTR Game.ColorLum[0],0
        MOV   DWORD PTR Game.ColorLum[4],0
        MOV   DWORD PTR Game.CLW,0
        MOV   DWORD PTR Game.CRW,0
        PUSH  WORD PTR Game.TIA_Count
        MOV   WORD PTR Game.TIA_Count,8
        PUSH  WORD PTR Game.DoHMOVE
        MOV   BYTE PTR Game.DoHMOVE,0
        PUSHAD
        CALL  Handle_TIA
        POPAD
        POP   WORD PTR Game.DoHMOVE
        POP   WORD PTR Game.TIA_Count
        POP   DWORD PTR Game.CRW
        POP   DWORD PTR Game.CLW
        POP   DWORD PTR Game.ColorLum[4]
        POP   DWORD PTR Game.ColorLum[0]
        POP   WORD PTR TIA_Latch_Check

        ; Recall collisions from previous run

        PUSH  AX
        MOV   AX,WORD PTR Game.Input_Byte[6]
        AND   AX,0C080h
        MOV   BP,AX
        SHR   BP,2
        MOV   AX,WORD PTR Game.Input_Byte[4]
        AND   AX,0C0C0h
        OR    BP,AX
        SHR   BP,2
        MOV   AX,WORD PTR Game.Input_Byte[2]
        AND   AX,0C0C0h
        OR    BP,AX
        SHR   BP,2
        MOV   AX,WORD PTR Game.Input_Byte[0]
        AND   AX,0C0C0h
        OR    BP,AX
        POP   AX



        SUB   EBX,EBX
        SUB   ESI,ESI
        MOVZX ESI,WORD PTR Game.LineStart
        ADD   ESI,DWORD PTR ScnPtr
        MOV   DWORD PTR [ESI],EBX
        MOV   DWORD PTR [ESI + 4],EBX
        MOV   BL,AH
        CMP   BL,8
        JBE   SHORT @No
        MOV   BL,8
@No:
        SUB   BL,AL
        ADD   AL,BL
        ADD   EDI,EBX
@HMOVEOk:
        CMP   AL,8
        JA    @HMOVEDone
        CMP   AH,8
        JB    @HMOVEDone
        MOV   BYTE PTR Game.DoHMOVE,0
@HMOVEDone:
        CMP   AH,AL

  ; Make sure that the end is greater than the start

        JA    SHORT @NotSame
        JMP   @Exiting
@NotSame:

  ; If vertical blanking is on, output black

        TEST  BYTE PTR Game.TIA_Regs[VBLANK],2
        JZ    SHORT @NotBlank
        TEST  BYTE PTR Game.TopVBLANK,0FFh
        JNZ   SHORT @ContinueBlank
        JMP   @Exiting
@ContinueBlank:
        CLD
        SUB   ECX,ECX
        MOV   CL,AH
        SUB   CL,AL
        SUB   EAX,EAX
        TEST  ECX,3
        JZ    SHORT @DoFourA
        MOV   EBX,ECX
        AND   ECX,3
        REP   STOSB
        MOV   ECX,EBX
@DoFourA:
        SHR   ECX,2
        JZ    SHORT @DoneFourA
        REP   STOSD
@DoneFourA:
        JMP   @Exiting

  ; Vertical blanking is off

@NotBlank:

        MOV   BYTE PTR Limit,AH
        AND   EAX,0FFh
        MOV   DH,0FFh

  ; Jump via the jump table

        MOV   BL,BYTE PTR Game.DispJump
        AND   EBX,3Eh
        ADD   EBX,EBX
        JMP   DWORD PTR Handle_TIA_Jump[EBX]

; -------------------------------------------------------------------------
; This code is used exclusively for 160x200x256 mode
; -------------------------------------------------------------------------

DoBL160:

; -------------------------------------------------------------------------
; Displaying BL
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and P1CBase and M0CBase and M1CBase> 0 0 0 0 1
        JMP   @Exiting

DoM1BL160:

; -------------------------------------------------------------------------
; Displaying M1 and BL
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and P1CBase and M0CBase> 0 0 0 1 1
        JMP   @Exiting

DoM0BL160:

; -------------------------------------------------------------------------
; Displaying M0 and BL
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and P1CBase and M1CBase> 0 1 0 0 1
        JMP   @Exiting

DoM0M1BL160:

; -------------------------------------------------------------------------
; Displaying M0,M1, and BL
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and P1CBase> 0 1 0 1 1
        JMP   @Exiting

DoP1BL160:

; -------------------------------------------------------------------------
; Displaying P1 and BL
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and M0CBase and M1CBase> 0 0 1 0 1
        JMP   @Exiting

DoM1P1BL160:

; -------------------------------------------------------------------------
; Displaying P1,M1, and BL
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and M0CBase> 0 0 1 1 1
        JMP   @Exiting

DoM0P1BL160:

; -------------------------------------------------------------------------
; Displaying M0,P1, and BL
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and M1CBase> 0 1 1 0 1
        JMP   @Exiting

DoM0P1M1BL160:

; -------------------------------------------------------------------------
; Displaying M0,P1,M1, and BL
; -------------------------------------------------------------------------

        _Disp160 <P0CBase> 0 1 1 1 1
        JMP   @Exiting

DoP0BL160:

; -------------------------------------------------------------------------
; Displaying P0 and BL
; -------------------------------------------------------------------------

        _Disp160 <P1CBase and M0CBase and M1CBase> 1 0 0 0 1
        JMP   @Exiting

DoP0M1BL160:

; -------------------------------------------------------------------------
; Displaying P0,M1, and BL
; -------------------------------------------------------------------------

        _Disp160 <P1CBase and M0CBase> 1 0 0 1 1
        JMP   @Exiting

DoP0M0BL160:

; -------------------------------------------------------------------------
; Displaying P0,M0, and BL
; -------------------------------------------------------------------------

        _Disp160 <P1CBase and M1CBase> 1 1 0 0 1
        JMP   @Exiting

DoP0M0M1BL160:

; -------------------------------------------------------------------------
; Displaying P0,M0,M1, and BL
; -------------------------------------------------------------------------

        _Disp160 <P1CBase> 1 1 0 1 1
        JMP   @Exiting

DoP0P1BL160:

; -------------------------------------------------------------------------
; Displaying P0,P1, and BL
; -------------------------------------------------------------------------

        _Disp160 <M0CBase and M1CBase> 1 0 1 0 1
        JMP   @Exiting

DoP0P1M1BL160:

; -------------------------------------------------------------------------
; Displaying P0,P1,M1, and BL
; -------------------------------------------------------------------------

        _Disp160 <M0CBase> 1 0 1 1 1
        JMP   @Exiting

DoP0M0P1BL160:

; -------------------------------------------------------------------------
; Displaying P0,M0,P1, and BL
; -------------------------------------------------------------------------

        _Disp160 <M1CBase> 1 1 1 0 1
        JMP   @Exiting

DoP0M0P1M1BL160:

; -------------------------------------------------------------------------
; Displaying P0,M0,P1,M1, and BL
; -------------------------------------------------------------------------

        _Disp160 <0FFFFh> 1 1 1 1 1
        JMP   @Exiting

DoNothing160:

; -------------------------------------------------------------------------
; Displaying nothing (playfield only)
; -------------------------------------------------------------------------

        CMP   BYTE PTR Limit,80
        JAE   @MaybeRight160
        _DispLeftNothing160
        JMP   @Exiting
@MaybeRight160:
        CMP   AL,80
        JAE   @OnlyRight160
        _DispNothing160
        JMP   @Exiting
@OnlyRight160:
        _DispRightNothing160
        JMP   @Exiting

;        _Disp160 <P0CBase and P1CBase and M0CBase and m1CBase and BLCBase> 0 0 0 0 0
;        JMP   @Exiting

DoM1160:

; -------------------------------------------------------------------------
; Displaying M1
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and P1CBase and M0CBase and BLCBase> 0 0 0 1 0
        JMP   @Exiting

DoM0160:

; -------------------------------------------------------------------------
; Displaying M0
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and P1CBase and M1CBase and BLCBase> 0 1 0 0 0
        JMP   @Exiting

DoM0M1160:

; -------------------------------------------------------------------------
; Displaying M0 and M1
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and P1CBase and BLCBase> 0 1 0 1 0
        JMP   @Exiting

DoP1160:

; -------------------------------------------------------------------------
; Displaying P1
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and M0CBase and M1CBase and BLCBase> 0 0 1 0 0
        JMP   @Exiting

DoM1P1160:

; -------------------------------------------------------------------------
; Displaying P1 and M1
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and M0CBase and BLCBase> 0 0 1 1 0
        JMP   @Exiting

DoM0P1160:

; -------------------------------------------------------------------------
; Displaying M0 and P1
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and M1CBase and BLCBase> 0 1 1 0 0
        JMP   @Exiting

DoM0P1M1160:

; -------------------------------------------------------------------------
; Displaying M0,P1, and M1
; -------------------------------------------------------------------------

        _Disp160 <P0CBase and BLCBase> 0 1 1 1 0
        JMP   @Exiting

DoP0160:

; -------------------------------------------------------------------------
; Displaying P0
; -------------------------------------------------------------------------

        _Disp160 <P1CBase and M0CBase and M1CBase and BLCBase> 1 0 0 0 0
        JMP   @Exiting

DoP0M1160:

; -------------------------------------------------------------------------
; Displaying P0 and M1
; -------------------------------------------------------------------------

        _Disp160 <P1CBase and M0CBase and BLCBase> 1 0 0 1 0
        JMP   @Exiting

DoP0M0160:

; -------------------------------------------------------------------------
; Displaying P0 and M0
; -------------------------------------------------------------------------

        _Disp160 <P1CBase and M1CBase and BLCBase> 1 1 0 0 0
        JMP   @Exiting

DoP0M0M1160:

; -------------------------------------------------------------------------
; Displaying P0,M0, and M1
; -------------------------------------------------------------------------

        _Disp160 <P1CBase and BLCBase> 1 1 0 1 0
        JMP   @Exiting

DoP0P1160:

; -------------------------------------------------------------------------
; Displaying P0 and P1
; -------------------------------------------------------------------------

        _Disp160 <M0CBase and M1CBase and BLCBase> 1 0 1 0 0
        JMP   @Exiting

DoP0P1M1160:

; -------------------------------------------------------------------------
; Displaying P0,P1, and M1
; -------------------------------------------------------------------------

        _Disp160 <M0CBase and BLCBase> 1 0 1 1 0
        JMP   @Exiting

DoP0M0P1160:

; -------------------------------------------------------------------------
; Displaying P0,M0, and P1
; -------------------------------------------------------------------------

        _Disp160 <M1CBase and BLCBase> 1 1 1 0 0
        JMP   @Exiting

DoP0M0P1M1160:

; -------------------------------------------------------------------------
; Displaying P0,M0,P1, and M1
; -------------------------------------------------------------------------

        _Disp160 <BLCBase> 1 1 1 1 0

; -------------------------------------------------------------------------

@Exiting:

  ; Unpack collisions and add to the existing ones

        OR    DWORD PTR Game.Input_Byte[0],EBP
        SHL   EBP,2
        OR    DWORD PTR Game.Input_Byte[2],EBP
        SHL   EBP,2
        OR    DWORD PTR Game.Input_Byte[4],EBP
        SHL   EBP,2
        OR    DWORD PTR Game.Input_Byte[6],EBP
        AND   DWORD PTR Game.Input_Byte[0],0C0C0C0C0h
        AND   DWORD PTR Game.Input_Byte[4],0C080C0C0h
        OR    DWORD PTR Game.Input_Byte[0],013000100h ; 003001100h
        OR    DWORD PTR Game.Input_Byte[4],001010101h

  ; Cleanup

        SUB   EDI,DWORD PTR ScnPtr
        MOV   DWORD PTR Game.Addr,EDI
        MOVSX EAX,WORD PTR Game.TIA_Count
        MOV   WORD PTR Game.Old_TIA_Count,AX

@ExitP:

  ; Restore registers

        POPAD
        RET

Handle_TIA endp
        end
