; "Fast Action Graphics"
; ----------------------
;    Using Foreground/Background Processing
;    Author Not Stated, but probably by John Perkins (??)
;    Published in "Arcadian" Vol 2, No. 10 (Sept 17. 1980)
;
;    - The program has been disassembled using using DZ80 2.0 
;      by Adam Trionfo on August 15, 2011.  This program can 
;      be assembled using ZMac.
;    - Most of these comments in this program are from the 
;      original article in the arcadian. 
;
;    This program runs on a Bally/Astrocade in the expansion RAM
; beginning at $6000.  This program was originally meant to 
; be entered into the Blue Ram Utility as a machine language 
; program.  This is still a method that works well to enter to program,
; thus the hexadedimal machine language code for the entire 119 byte 
; program is given here:
;
;          0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
; $6000 - F3 D9 3E 60 ED 47 3E 18  D3 0D 21 6A 60 11 00 70
; $6010 - 01 0D 00 ED B0 D9 FB C9  1A 60 CD B0 20 ED 73 7E
; $6020 - 70 31 7E 70 F5 C5 D5 E5  DD E5 FD E5 DB 1C 32 02
; $6030 - 70 FF 00 07 4C 60 3F 00  70 52 60 07 4C 60 02 FD
; $6040 - E1 DD E1 E1 D1 C1 F1 ED  7B 7E 70 C9 1F 00 70 56
; $6050 - 60 08 00 98 00 50 00 00  02 08 28 00 82 00 82 00
; $6060 - A8 2A 80 80 80 A8 00 80  00 2A 20 80 00 05 00 00
; $6070 - 00 03 05 00 00 00 03
; 
; Description:
; ------------
;    Fast Action Graphics are demonstrated in this machine code background
; routine.  Enter this program using your Blue Ram Utility and watch
; the Perkin's Engineering graphic (a "PE") bounce around the screen 
; without disturbing what is there!
;    The speed of motion is controlled by the #1 knob.  Another special 
; effect produced by this routine is a "curtain of invisibility" at the 
; top of the screen.  As the graphic moves behind the curtain, it
; disappears one-half pixel at a time.  The size of the curtain is also 
; controlled by the #1 knob.  Notice that you can still enter programs, 
; etc. in BASIC because the graphic movement is performed in the
; background mode where it does not tie up the processor.
;
;    To Stop the background process from the foreground process using BASIC,
; enter: :RETURN [GO].  To Start it up again, enter: CALL 24576 [GO]
;

        INCLUDE "HVGLIB.H"       ; Home Video Game Library

        ORG     $6000            ; First Byte of Blue Ram Expansion Memory

        DI                       ; Disable the Current Background Process      
; Reassign background processing to a routine whose beginning address
; can be found in the word at location $6018.
        EXX      
        LD      A,$60            ; High Order Byte Address of Interrupt Vector
        LD      I,A              ; Load Interrupt Vector Register
        LD      A,$18            ; Low Order Byte Address of Interrupt Vector 
        OUT     (INFBK),A        ; Port $0D, Write INterrupt FeedBacK

; Move a 13-byte Motion Control Table (aka Vector Table) into
; the $7000 area so that this routine can operate in the ROM
; mode if desired.
L600A:  LD      HL,L606A         ; Source Address 
        LD      DE,$7000         ; Destination Address
        LD      BC,$000D         ; Load Counter with 13 
        LDIR
; Reanable the background processor
        EXX     
        EI      
        RET     ; Return to the program program from which it was called     

L6018:  DW      L601A            ; Points to Interrupt Routine 

; Envoke the original Background Processor.  This is necessary so
; that the note timer can be decremented as required when printing
; characters.  Otherwise, the foreground program would hang up
; while waiting for the timer to clear and not be able to continue
; with the foreground program. 
;L601A:  CALL    $20B0            ; Envoke the Bally BASIC original Background Processor
L601A:   CALL    $21FD            ; Call AstroBASIC's Interrupt Routine ("BG Processor")

; Save all the Z80 registers so that their original values can
; be returned to the foreground program.
        LD      ($707E),SP       ; Load the contents of SP to expansion RAM
        LD      SP,$707E         ; Move the Stack point to expansion RAM
        PUSH    AF
        PUSH    BC
        PUSH    DE
        PUSH    HL
        PUSH    IX
        PUSH    IY

; Read the #1 controller knob and place the value in the motion
; control table at the current motion velocity multiplier.
        IN      A,(POT0)         ; Pot $1C, Read POTentiometer 0 for player 1 knob
        LD      ($7000+VBTIMB),A ; Place Knob Value into Time Base
; Invoke special graphics and animation services built into the Bally
; Arcade internal ROM.  
        SYSTEM  INTPC            ; UPI INTerPret with Context 
        ;
        DO      MCALL            ; UPI Macro CALL interpreter 
        DW      L604C            ; Macro Address
        ;
        DO      VECT             ; UPI VECTor move coordinate 
        DW      $7000            ; Vector Block
        DW      L6052            ; Limit Table (AKA Motion Control Table)
        ;
        DO      MCALL            ; UPI Macro CALL interpreter 
        DW      L604C            ; Macro Address
        ;
        DONT    XINTC            ; UPI eXit INTerpreter with 
        ;
; Restore the Z80 registers to their original values and return
; to the foreground program in progress.
        POP     IY
        POP     IX
        POP     HL
        POP     DE
        POP     BC
        POP     AF
        LD      SP,($707E)       ; Restore the contents of the SP
        RET     

; Write Pattern to Screen
; This Macro is called from the ROM Interpreter using MCALL.
L604C:  DO      VWRITR           ; UPI Vector WRITe Relative
        DW      $7000            ; Vector Block
        DW      L6056            ; Pattern Address = 24662
        DONT    MRET             ; Return from to ROM Interpreter

; Limite Table for VECT Routine - Define the boundaries of the 
; graphic motion. (152 Pixels Wide and 40 High)
L6052:  DB      0                ; X Lower Limit
        DB      152              ; X Upper Limit
        DB      0                ; Y Lower Limit 
        DB      80               ; Y Upper Limit

; Pattern Address
; Define the Corordinate Reference for the graphic (0,0) and
; the size of the graphic (8 x 8 pixels).
L6056:  DB      0,0                 ; X,Y Displacement
        DB      2,8                 ; Width and Height (2 Bytes x 8 bytes)
; The graphic data of the "PE" Image.  Note that only the odd bits
; are used.  This is very important when working with this BASIC
; since even bits store the actual program statements.  If these
; even bits are disturbed, the BASIC program will be altered,
; usually catastrophically.
L605A:  DB      00101000B,00000000B ; . 2 2 . . . . .      
        DB      10000010B,00000000B ; 2 . . 2 . . . .
        DB      10000010B,00000000B ; 2 . . 2 . . . .
        DB      10101000B,00101010B ; 2 2 2 . . 2 2 2
        DB      10000000B,10000000B ; 2 . . . 2 . . .
        DB      10000000B,10101000B ; 2 . . . 2 2 2 .
        DB      00000000B,10000000B ; . . . . 2 . . .
        DB      00000000B,00101010B ; . . . . . 2 2 2

; Vector Block (Accessed from $7000)
; Defines the constraints for the motion control table.
; These values define 5/256'ths of a pixel times the
; current velocity multiplier worth of motion in both
; the X and Y coordinates with each update (60 times
; per second).  The fastest speed, therefore, is 5 pixels
; x 60 updates = 300 pixels per second.  The "$03's" in
; the table indicate that the graphic is to bounce off the
; sides instead of stopping.  
L606A:  DB      $20              ; Magic Register  (VBMR)
        DB      $80              ; Vector Status   (VBSTAT)
        DB      $00              ; Time Base       (VBTIMB)         
        DB      $05              ; Delta X Low     (VBDXL)               
        DB      $00              ; Delta X High    (VBDXH)
        DB      $00              ; X Position Low  (VBXL)              
        DB      $00              ; X Position High (VBXH)
        DB      $03              ; X Checks Mask   (VBXCHK)               
        DB      $05              ; Delta Y Low     (VBDYL)               
        DB      $00              ; Delta Y High    (VBDHL)
        DB      $00              ; Y Position Low  (VBYL)
        DB      $00              ; Y Position High (VBYH)
        DB      $03              ; Y Checks Mask   (VBYCHK)
        