Difference between revisions of "Tagalong Todd Tutorial: Part 2 - Files"

From Intellivision Wiki
Jump to: navigation, search
(tag2b.asm)
(tag2a.asm)
Line 3: Line 3:
 
This is the code for the first version built in the tutorial - the player graphic moves across the screen quite rapidly.
 
This is the code for the first version built in the tutorial - the player graphic moves across the screen quite rapidly.
  
    ;;==========================================================================;;
+
<code><pre>
    ;; Joe Zbiciak's Tagalong Todd!                                            ;;
+
;;==========================================================================;;
    ;; Copyright 2002, Joe Zbiciak, intvnut AT gmail.com.                      ;;
+
;; Joe Zbiciak's Tagalong Todd!                                            ;;
    ;; http://spatula-city.org/~im14u2c/intv/                                  ;;
+
;; Copyright 2002, Joe Zbiciak, intvnut AT gmail.com.                      ;;
     ;;==========================================================================;;
+
;; http://spatula-city.org/~im14u2c/intv/                                  ;;
 +
;;==========================================================================;;
 +
 
 +
;* ======================================================================== *;
 +
;*  TO BUILD IN BIN+CFG FORMAT:                                            *;
 +
;*      as1600 -o tagalong.bin -l tagalong.lst tagalong.asm                *;
 +
;*                                                                          *;
 +
;*  TO BUILD IN ROM FORMAT:                                                *;
 +
;*      as1600 -o tagalong.rom -l tagalong.lst tagalong.asm                *;
 +
;* ======================================================================== *;
 +
 
 +
            ROMW    16              ; Use 16-bit ROM
 +
 
 +
;------------------------------------------------------------------------------
 +
; Include system information
 +
;------------------------------------------------------------------------------
 +
            INCLUDE "gimini.asm"
 +
 
 +
;------------------------------------------------------------------------------
 +
; Global constants and configuration.
 +
;------------------------------------------------------------------------------
 +
 
 +
TSKQM      EQU     $7              ; Task queue is 8 entries large
 +
MAXTSK      EQU    3              ; Only one task
 +
 
 +
;------------------------------------------------------------------------------
 +
; Allocate 8-bit variables in Scratch RAM
 +
;------------------------------------------------------------------------------
 +
SCRATCH    ORG    $100, $100, "-RWBN"
 +
 
 +
ISRVEC      RMB    2              ; Always at $100 / $101
 +
 
 +
            ; Task-oriented 8-bit variables
 +
TSKQHD      RMB    1              ; Task queue head
 +
TSKQTL      RMB    1              ; Task queue tail
 +
TSKDQ      RMB    2*(TSKQM+1)    ; Task data queue
 +
TSKACT      RMB    1              ; Number of active tasks
 +
 
 +
_SCRATCH    EQU    $              ; end of scratch area
 +
 
 +
 
 +
 
 +
;------------------------------------------------------------------------------
 +
; Allocate 16-bit variables in System RAM
 +
;------------------------------------------------------------------------------
 +
SYSTEM      ORG    $2F0, $2F0, "-RWBN"
 +
STACK      RMB    32              ; Reserve 32 words for the stack
 +
 
 +
            ; Task-oriented 16-bit variables
 +
TSKQ        RMB    (TSKQM + 1)    ; Task queue
 +
TSKTBL      RMB    (MAXTSK * 4)    ; Timer task table
 +
 
 +
            ; STIC shadow
 +
STICSH      RMB    24              ; Room for X, Y, and A regs only.
 +
 
 +
PLYR        PROC
 +
@@XP        RMB    1              ; X position
 +
@@YP        RMB    1              ; Y position
 +
            ENDP
 +
 
 +
MOB_BUSY    RMB    1
 +
_SYSTEM    EQU    $              ; end of system area
 +
 
 +
 
 +
;------------------------------------------------------------------------------
 +
; EXEC-friendly ROM header.
 +
;------------------------------------------------------------------------------
 +
            ORG    $5000          ; Use default memory map
 +
ROMHDR:    BIDECLE ZERO            ; MOB picture base  (points to NULL list)
 +
            BIDECLE ZERO            ; Process table      (points to NULL list)
 +
            BIDECLE MAIN            ; Program start address
 +
            BIDECLE ZERO            ; Bkgnd picture base (points to NULL list)
 +
            BIDECLE ONES            ; GRAM pictures      (points to NULL list)
 +
            BIDECLE TITLE          ; Cartridge title/date
 +
            DECLE  $03C0          ; No ECS title, run code after title,
 +
                                    ; ... no clicks
 +
ZERO:      DECLE  $0000          ; Screen border control
 +
            DECLE  $0000          ; 0 = color stack, 1 = f/b mode
 +
ONES:      DECLE  C_BLU, C_BLU    ; Initial color stack 0 and 1: Blue
 +
            DECLE  C_BLU, C_BLU    ; Initial color stack 2 and 3: Blue
 +
            DECLE  C_BLU          ; Initial border color: Blue
 +
;------------------------------------------------------------------------------
 +
 
 +
 
 +
;; ======================================================================== ;;
 +
;;  TITLE  -- Display our modified title screen & copyright date.          ;;
 +
;; ======================================================================== ;;
 +
TITLE:      PROC
 +
            STRING  102, "Tagalong Todd", 0
 +
            BEGIN
 +
         
 +
            ; Patch the title string to say '=JRMZ=' instead of Mattel.
 +
            CALL    PRINT.FLS      ; Write string (ptr in R5)
 +
            DECLE  C_WHT, $23D    ; White, Point to 'Mattel' in top-left
 +
            STRING  '=JRMZ='        ; Guess who?  :-)
 +
            STRING  ' Productions'
 +
            BYTE    0
 +
         
 +
            CALL    PRINT.FLS      ; Write string (ptr in R1)
 +
            DECLE  C_WHT, $2D0    ; White, Point to 'Mattel' in lower-right
 +
            STRING  '2002 =JRMZ='  ; Guess who?  :-)
 +
            BYTE    0
 +
         
 +
            ; Done.
 +
            RETURN                  ; Return to EXEC for title screen display
 +
            ENDP
 +
 
 +
 
 +
;; ======================================================================== ;;
 +
;;  MAIN:  Here's our main program code.                                    ;;
 +
;; ======================================================================== ;;
 +
MAIN:      PROC
 +
            DIS
 +
            MVII    #STACK, R6      ; Set up our stack
 +
 
 +
            MVII    #$25E,  R1      ;\
 +
            MVII    #$102,  R4      ; |-- Clear all of RAM memory
 +
            CALL    FILLZERO        ;/
 +
 
 +
            MVII    #INITISR, R0    ;\    Do GRAM initialization in ISR.
 +
            MVO    R0,    ISRVEC  ; |__ INITISR will the point to the
 +
            SWAP    R0              ; |  regular ISR when it's done.
 +
            MVO    R0,    ISRVEC+1;/   
 +
 
 +
            ;; ------------------------------------------------------------ ;;
 +
            ;;  Put the character on the screen                            ;;
 +
            ;; ------------------------------------------------------------ ;;
 +
            MVII    #$1000, R0
 +
            MVO    R0,    PLYR.XP
 +
            MVO    R0,    PLYR.YP
 +
 
 +
            EIS
 +
 
 +
            ;; ------------------------------------------------------------ ;;
 +
            ;;  Fall into the RUNQ.  We should never exit the RUNQ in this  ;;
 +
            ;;  demo, since we never call SCHEDEXIT.                        ;;
 +
            ;; ------------------------------------------------------------ ;;
 +
            CALL    RUNQ            ; Run until a SCHEDEXIT happens
 +
 
 +
            ;; ------------------------------------------------------------ ;;
 +
            ;;  If a SCHEDEXIT *does* happen (say, due to a bug), crash    ;;
 +
            ;;  gracefully.                                                ;;
 +
            ;; ------------------------------------------------------------ ;;
 +
            CALL    PRINT.FLS
 +
            DECLE  C_RED, $200 + 11*20
 +
                    ;01234567890123456789
 +
            STRING  "SCHEDEXIT WAS CALLED",0
 +
 
 +
            DECR    PC              ; Can't get here
 +
         
 +
            ENDP
 +
 
 +
;; ======================================================================== ;;
 +
;;  MOB_UPDATE -- This updates the player's position                        ;;
 +
;; ======================================================================== ;;
 +
MOB_UPDATE  PROC
 +
            PSHR    R5
 +
 
 +
            ;; ------------------------------------------------------------ ;;
 +
            ;;  Merge our position with our MOB registers.                  ;;
 +
            ;; ------------------------------------------------------------ ;;
 +
            MVII    #@@mobr,    R4      ; MOB information template
 +
            MVII    #STICSH,    R5
 +
 
 +
            MVI    PLYR.XP,    R0      ;\
 +
            SWAP    R0                  ; |
 +
            ANDI    #$00FF,    R0      ; |- Player X position
 +
            XOR@    R4,        R0      ; |
 +
            MVO@    R0,        R5      ;/
 +
         
 +
            ADDI    #7,        R5      ;  Move pointer to Y coordinate section of the STICSH
 +
           
 +
            MVI    PLYR.YP,    R0      ;\
 +
            SWAP    R0                  ; |
 +
            ANDI    #$007F,    R0      ; |- Player Y position
 +
            XOR@    R4,        R0      ; |
 +
            MVO@    R0,        R5      ;/
 +
 
 +
            ADDI    #7,        R5      ; Move pointer to A register section of the STICSH
 +
 
 +
            MVI@    R4,        R0      ; \_ Player's A register
 +
            MVO@    R0,        R5      ; /
 +
 
 +
            CLRR    R0
 +
            MVO    R0,        MOB_BUSY
 +
 
 +
            PULR    PC
 +
 
 +
            ;; ------------------------------------------------------------ ;;
 +
            ;;  Bits to copy into MOB registers.                            ;;
 +
            ;; ------------------------------------------------------------ ;;
 +
@@mobr      DECLE  STIC.mobx_visb      ; make player visible
 +
            DECLE  STIC.moby_yres      ; make player 8x16 MOB
 +
            DECLE  STIC.moba_fg1 + STIC.moba_gram + 0*8    ; Player is blue
 +
            ENDP
 
      
 
      
    ;* ======================================================================== *;
+
 
    ;* TO BUILD IN BIN+CFG FORMAT:                                            *;
+
;; ======================================================================== ;;
    ;*      as1600 -o tagalong.bin -l tagalong.lst tagalong.asm                *;
+
;; ISR -- Just keep the screen on, and copy the STIC shadow over.         ;;
    ;*                                                                          *;
+
;; ======================================================================== ;;
    ;*  TO BUILD IN ROM FORMAT:                                                *;
+
ISR        PROC
    ;*      as1600 -o tagalong.rom -l tagalong.lst tagalong.asm                *;
+
 
    ;* ======================================================================== *;
+
            ;; ------------------------------------------------------------ ;;
   
+
            ;;  Basics:  Update color stack and video enable.              ;;
                ROMW    16              ; Use 16-bit ROM
+
            ;; ------------------------------------------------------------ ;;
   
+
            MVO    R0,    STIC.viden  ; Enable display
    ;------------------------------------------------------------------------------
+
            MVI     STIC.mode, R0      ; ...in color-stack mode
    ; Include system information
+
 
    ;------------------------------------------------------------------------------
+
            MVII    #C_GRY, R0          ;\
                INCLUDE "gimini.asm"
+
            MVO    R0,    STIC.cs0    ; |__ Set display to grey
   
+
            MVO    R0,    STIC.cs2    ; |
     ;------------------------------------------------------------------------------
+
            MVO    R0,    STIC.bord  ;/
    ; Global constants and configuration.
+
 
    ;------------------------------------------------------------------------------
+
            ;; ------------------------------------------------------------ ;;
      
+
            ;;  Update STIC shadow and queue updates for MOB velocities.    ;;
    TSKQM      EQU    $7              ; Task queue is 8 entries large
+
            ;; ------------------------------------------------------------ ;;
     MAXTSK      EQU     3              ; Only one task
+
            MVI     MOB_BUSY, R0
   
+
            TSTR    R0
    ;------------------------------------------------------------------------------
+
            BNEQ    @@no_mobs
    ; Allocate 8-bit variables in Scratch RAM
+
            MVO     PC,     MOB_BUSY
    ;------------------------------------------------------------------------------
+
 
    SCRATCH    ORG    $100, $100, "-RWBN"
+
 
   
+
            CALL    MEMCPY              ;\__ Copy over the STIC shadow.
    ISRVEC      RMB    2              ; Always at $100 / $101
+
            DECLE  $0000, STICSH, 24  ;/
   
+
 
                ; Task-oriented 8-bit variables
+
            MVII    #MOB_UPDATE, R0
    TSKQHD      RMB    1              ; Task queue head
+
            JSRD    R5,  QTASK
    TSKQTL      RMB    1              ; Task queue tail
+
 
    TSKDQ      RMB    2*(TSKQM+1)    ; Task data queue
+
            MVII    #MOVE_PLAYER, R0
    TSKACT      RMB    1              ; Number of active tasks
+
            JSRD    R5,  QTASK
   
+
 
    _SCRATCH    EQU    $              ; end of scratch area
+
@@no_mobs: 
   
+
 
   
+
            CALL    DOTIMER            ; Update timer-based tasks.
   
+
            B      $1014              ; return from interrupt.
    ;------------------------------------------------------------------------------
+
            ENDP
    ; Allocate 16-bit variables in System RAM
+
 
     ;------------------------------------------------------------------------------
+
 
    SYSTEM     ORG     $2F0, $2F0, "-RWBN"
+
;; ======================================================================== ;;
    STACK      RMB    32              ; Reserve 32 words for the stack
+
;;  MOVE_PLAYER -- Just programatically move the player around a bit.      ;;
      
+
;; ======================================================================== ;;
                ; Task-oriented 16-bit variables
+
MOVE_PLAYER PROC
    TSKQ        RMB    (TSKQM + 1)    ; Task queue
+
            PSHR    R5
    TSKTBL      RMB    (MAXTSK * 4)    ; Timer task table
+
 
   
+
            ; Just for something to do we'll move across the screen, then
                ; STIC shadow
+
            ; down a row and back across, again and again until we get to the
    STICSH      RMB    24              ; Room for X, Y, and A regs only.
+
            ; bottom at which time we'll start over
   
+
 
    PLYR        PROC
+
            MVI     PLYR.XP,    R0      ;\
    @@XP        RMB    1              ; X position
+
            SWAP    R0                  ; >-- Get player X position
     @@YP        RMB    1              ; Y position
+
            ANDI    #$00FF,    R0      ;/
                ENDP
+
 
      
+
            ADDI    #8,        R0      ; move 8 X positions to the right
    MOB_BUSY   RMB    1
+
 
    _SYSTEM    EQU    $              ; end of system area
+
            MVII    #159,      R1      ;\__ compare X against the right edge of the screen
      
+
            CMPR    R0,        R1     ;/
   
+
            BLT     @@fixx
    ;------------------------------------------------------------------------------
+
 
     ; EXEC-friendly ROM header.
+
            SWAP    R0                  ; put the integer part back into the upper byte
     ;------------------------------------------------------------------------------
+
            MVO     R0,    PLYR.XP      ; update the X position
                ORG     $5000          ; Use default memory map
+
            B      @@done              ; we're done
    ROMHDR:    BIDECLE ZERO            ; MOB picture base  (points to NULL list)
+
 
                BIDECLE ZERO            ; Process table     (points to NULL list)
+
            ; here we've hit the right edge of the screen and should move down a row
                BIDECLE MAIN            ; Program start address
+
@@fixx      MVII    #0,        R0      ;\__ set X position back to zero
                BIDECLE ZERO            ; Bkgnd picture base (points to NULL list)
+
            MVO     R0,    PLYR.XP      ;/
                BIDECLE ONES            ; GRAM pictures      (points to NULL list)
+
 
                BIDECLE TITLE          ; Cartridge title/date
+
            MVI     PLYR.YP,   R0      ;\
                DECLE  $03C0          ; No ECS title, run code after title,
+
            SWAP    R0                  ; >-- Get player Y position
                                        ; ... no clicks
+
            ANDI    #$007F,     R0      ;/
    ZERO:      DECLE  $0000          ; Screen border control
+
 
                DECLE  $0000          ; 0 = color stack, 1 = f/b mode
+
            ADDI    #8,        R0      ;  move 8 Y positions down
    ONES:      DECLE  C_BLU, C_BLU    ; Initial color stack 0 and 1: Blue
+
 
                DECLE  C_BLU, C_BLU    ; Initial color stack 2 and 3: Blue
+
            MVII    #96,        R1      ;\__ compare Y against the bottom edge of the screen
                DECLE  C_BLU          ; Initial border color: Blue
+
            CMPR    R0,        R1      ;/
    ;------------------------------------------------------------------------------
+
            BLT     @@fixy
   
+
 
   
+
            SWAP    R0                  ; put the integer part back into the upper byte
    ;; ======================================================================== ;;
+
            MVO     R0,    PLYR.YP      ; update the Y position
    ;;  TITLE  -- Display our modified title screen & copyright date.          ;;
+
            B      @@done
    ;; ======================================================================== ;;
+
           
    TITLE:      PROC
+
            ; here we've hit the bottom edge of the screen and should move to the top
                STRING 102, "Tagalong Todd", 0
+
@@fixy      MVII    #0,        R0      ;\__ set Y position back to zero
                BEGIN
+
            MVO     R0,    PLYR.YP      ;/
             
+
 
                ; Patch the title string to say '=JRMZ=' instead of Mattel.
+
@@done     PULR    PC
                CALL    PRINT.FLS      ; Write string (ptr in R5)
+
            ENDP
                DECLE  C_WHT, $23D    ; White, Point to 'Mattel' in top-left
+
 
                STRING  '=JRMZ='        ; Guess who?  :-)
+
;; ======================================================================== ;;
                STRING  ' Productions'
+
;;  INITISR -- Copy our GRAM image over, and then do the plain ISR.        ;;
                BYTE    0
+
;; ======================================================================== ;;
             
+
INITISR    PROC
                CALL    PRINT.FLS      ; Write string (ptr in R1)
+
            PSHR    R5
                DECLE  C_WHT, $2D0    ; White, Point to 'Mattel' in lower-right
+
 
                STRING  '2002 =JRMZ='  ; Guess who?  :-)
+
            CALL    MEMCPY
                BYTE    0
+
            DECLE  $3800, GRAMIMG, GRAMIMG.end - GRAMIMG
             
+
 
                ; Done.
+
            MVII    #ISR,  R0
                RETURN                  ; Return to EXEC for title screen display
+
            MVO    R0,    ISRVEC
                ENDP
+
            SWAP    R0
   
+
            MVO    R0,    ISRVEC + 1
   
+
 
    ;; ======================================================================== ;;
+
            PULR    PC
    ;;  MAIN:  Here's our main program code.                                    ;;
+
            ENDP
    ;; ======================================================================== ;;
+
 
    MAIN:      PROC
+
;; ======================================================================== ;;
                DIS
+
;; GRAMIMG -- Arrow pictures and other graphics to load into GRAM.         ;;
                MVII    #STACK, R6     ; Set up our stack
+
;; ======================================================================== ;;
   
+
GRAMIMG    PROC
                MVII    #$25E,  R1      ;\
+
 
                MVII    #$102,  R4      ; |-- Clear all of RAM memory
+
@@person:  ; Crappy person graphic.
                CALL    FILLZERO        ;/
+
            DECLE  %00010000
   
+
            DECLE  %00111000
                MVII    #INITISR, R0    ;\    Do GRAM initialization in ISR.
+
            DECLE  %00111000
                MVO    R0,    ISRVEC  ; |__ INITISR will the point to the
+
            DECLE  %00010000
                SWAP    R0              ; |  regular ISR when it's done.
+
            DECLE  %00010000
                MVO    R0,    ISRVEC+1;/   
+
            DECLE  %01111100
   
+
            DECLE  %10111010
                ;; ------------------------------------------------------------ ;;
+
            DECLE  %10111010
                ;; Put the character on the screen                            ;;
+
            DECLE  %10111010
                ;; ------------------------------------------------------------ ;;
+
            DECLE  %10111010
                MVII    #$1000, R0
+
            DECLE  %00111000
                MVO    R0,    PLYR.XP
+
            DECLE  %00101000
                MVO    R0,    PLYR.YP
+
            DECLE  %00101000
   
+
            DECLE  %00101000
                EIS
+
            DECLE  %00101000
   
+
            DECLE  %01101100
                ;; ------------------------------------------------------------ ;;
+
@@end:      
                ;;  Fall into the RUNQ.  We should never exit the RUNQ in this  ;;
+
            ENDP
                ;demo, since we never call SCHEDEXIT.                       ;;
+
 
                ;; ------------------------------------------------------------ ;;
+
;; ======================================================================== ;;
                CALL    RUNQ            ; Run until a SCHEDEXIT happens
+
;; LIBRARY INCLUDES                                                        ;;
   
+
;; ======================================================================== ;;
                ;; ------------------------------------------------------------ ;;
+
            INCLUDE "print.asm"      ; PRINT.xxx routines
                ;If a SCHEDEXIT *does* happen (say, due to a bug), crash    ;;
+
            INCLUDE "fillmem.asm"    ; CLRSCR/FILLZERO/FILLMEM
                ;;  gracefully.                                                 ;;
+
            INCLUDE "memcpy.asm"      ; MEMCPY
                ;; ------------------------------------------------------------ ;;
+
            INCLUDE "timer.asm"          ; Timer-based task stuff
                CALL    PRINT.FLS
+
            INCLUDE "taskq.asm"          ; RUNQ/QTASK
                DECLE  C_RED, $200 + 11*20
+
 
                        ;01234567890123456789
+
 
                STRING  "SCHEDEXIT WAS CALLED",0
+
;* ======================================================================== *;
   
+
;*  This program is free software; you can redistribute it and/or modify    *;
                DECR    PC              ; Can't get here
+
;*  it under the terms of the GNU General Public License as published by    *;
             
+
;*  the Free Software Foundation; either version 2 of the License, or      *;
                ENDP
+
;* (at your option) any later version.                                     *;
   
+
;*                                                                          *;
    ;; ======================================================================== ;;
+
;*  This program is distributed in the hope that it will be useful,        *;
    ;;  MOB_UPDATE -- This updates the player's position                        ;;
+
;*  but WITHOUT ANY WARRANTY; without even the implied warranty of          *;
    ;; ======================================================================== ;;
+
;*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *;
    MOB_UPDATE  PROC
+
;*  General Public License for more details.                                *;
                PSHR    R5
+
;*                                                                          *;
   
+
;*  You should have received a copy of the GNU General Public License      *;
                ;; ------------------------------------------------------------ ;;
+
;*  along with this program; if not, write to the Free Software            *;
                ;;  Merge our position with our MOB registers.                  ;;
+
;* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               *;
                ;; ------------------------------------------------------------ ;;
+
;* ======================================================================== *;
                MVII    #@@mobr,    R4      ; MOB information template
+
;*                   Copyright (c) 2002, Joseph Zbiciak                    *;
                MVII    #STICSH,    R5
+
;* ======================================================================== *;
   
+
</pre></code>
                MVI    PLYR.XP,    R0      ;\
 
                SWAP    R0                  ; |
 
                ANDI    #$00FF,    R0      ; |- Player X position
 
                XOR@    R4,        R0      ; |
 
                MVO@    R0,        R5      ;/
 
             
 
                ADDI    #7,        R5      ;  Move pointer to Y coordinate section of the STICSH
 
               
 
                MVI    PLYR.YP,    R0      ;\
 
                SWAP    R0                  ; |
 
                ANDI    #$007F,    R0      ; |- Player Y position
 
                XOR@    R4,        R0      ; |
 
                MVO@    R0,        R5      ;/
 
   
 
                ADDI    #7,        R5      ; Move pointer to A register section of the STICSH
 
   
 
                MVI@    R4,        R0      ; \_ Player's A register
 
                MVO@    R0,        R5      ; /
 
   
 
                CLRR    R0
 
                MVO    R0,        MOB_BUSY
 
   
 
                PULR    PC
 
   
 
                ;; ------------------------------------------------------------ ;;
 
                ;;  Bits to copy into MOB registers.                            ;;
 
                ;; ------------------------------------------------------------ ;;
 
    @@mobr      DECLE  STIC.mobx_visb      ; make player visible
 
                DECLE  STIC.moby_yres      ; make player 8x16 MOB
 
                DECLE  STIC.moba_fg1 + STIC.moba_gram + 0*8    ; Player is blue
 
                ENDP
 
       
 
   
 
    ;; ======================================================================== ;;
 
    ;;  ISR -- Just keep the screen on, and copy the STIC shadow over.          ;;
 
    ;; ======================================================================== ;;
 
    ISR        PROC
 
   
 
                ;; ------------------------------------------------------------ ;;
 
                ;;  Basics:  Update color stack and video enable.              ;;
 
                ;; ------------------------------------------------------------ ;;
 
                MVO    R0,    STIC.viden  ; Enable display
 
                MVI    STIC.mode, R0      ; ...in color-stack mode
 
   
 
                MVII    #C_GRY, R0          ;\
 
                MVO    R0,    STIC.cs0    ; |__ Set display to grey
 
                MVO    R0,    STIC.cs2    ; |
 
                MVO    R0,    STIC.bord  ;/
 
   
 
                ;; ------------------------------------------------------------ ;;
 
                ;;  Update STIC shadow and queue updates for MOB velocities.    ;;
 
                ;; ------------------------------------------------------------ ;;
 
                MVI    MOB_BUSY, R0
 
                TSTR    R0
 
                BNEQ    @@no_mobs
 
                MVO    PC,    MOB_BUSY
 
   
 
   
 
                CALL    MEMCPY              ;\__ Copy over the STIC shadow.
 
                DECLE  $0000, STICSH, 24  ;/
 
   
 
                MVII    #MOB_UPDATE, R0
 
                JSRD    R5,  QTASK
 
   
 
                MVII    #MOVE_PLAYER, R0
 
                JSRD    R5,  QTASK
 
   
 
    @@no_mobs: 
 
   
 
                CALL    DOTIMER            ; Update timer-based tasks.
 
                B      $1014              ; return from interrupt.
 
                ENDP
 
   
 
   
 
    ;; ======================================================================== ;;
 
    ;;  MOVE_PLAYER -- Just programatically move the player around a bit.      ;;
 
    ;; ======================================================================== ;;
 
    MOVE_PLAYER PROC
 
                PSHR    R5
 
   
 
                ; Just for something to do we'll move across the screen, then
 
                ; down a row and back across, again and again until we get to the
 
                ; bottom at which time we'll start over
 
   
 
                MVI    PLYR.XP,    R0      ;\
 
                SWAP    R0                  ; >-- Get player X position
 
                ANDI    #$00FF,    R0      ;/
 
   
 
                ADDI    #8,        R0      ; move 8 X positions to the right
 
   
 
                MVII    #159,      R1      ;\__ compare X against the right edge of the screen
 
                CMPR    R0,        R1      ;/
 
                BLT    @@fixx
 
   
 
                SWAP    R0                  ; put the integer part back into the upper byte
 
                MVO    R0,    PLYR.XP      ; update the X position
 
                B      @@done              ; we're done
 
   
 
                ; here we've hit the right edge of the screen and should move down a row
 
    @@fixx      MVII    #0,        R0      ;\__ set X position back to zero
 
                MVO    R0,    PLYR.XP      ;/
 
   
 
                MVI    PLYR.YP,    R0      ;\
 
                SWAP    R0                  ; >-- Get player Y position
 
                ANDI    #$007F,    R0      ;/
 
   
 
                ADDI    #8,        R0      ;  move 8 Y positions down
 
   
 
                MVII    #96,        R1      ;\__ compare Y against the bottom edge of the screen
 
                CMPR    R0,        R1      ;/
 
                BLT    @@fixy
 
   
 
                SWAP    R0                  ; put the integer part back into the upper byte
 
                MVO    R0,    PLYR.YP      ; update the Y position
 
                B      @@done
 
               
 
                ; here we've hit the bottom edge of the screen and should move to the top
 
    @@fixy      MVII    #0,        R0      ;\__ set Y position back to zero
 
                MVO    R0,    PLYR.YP      ;/
 
   
 
    @@done      PULR    PC
 
                ENDP
 
   
 
    ;; ======================================================================== ;;
 
    ;;  INITISR -- Copy our GRAM image over, and then do the plain ISR.        ;;
 
    ;; ======================================================================== ;;
 
    INITISR    PROC
 
                PSHR    R5
 
   
 
                CALL    MEMCPY
 
                DECLE  $3800, GRAMIMG, GRAMIMG.end - GRAMIMG
 
   
 
                MVII    #ISR,  R0
 
                MVO    R0,    ISRVEC
 
                SWAP    R0
 
                MVO    R0,    ISRVEC + 1
 
   
 
                PULR    PC
 
                ENDP
 
   
 
    ;; ======================================================================== ;;
 
    ;;  GRAMIMG -- Arrow pictures and other graphics to load into GRAM.        ;;
 
    ;; ======================================================================== ;;
 
    GRAMIMG    PROC
 
   
 
    @@person:  ; Crappy person graphic.
 
                DECLE  %00010000
 
                DECLE  %00111000
 
                DECLE  %00111000
 
                DECLE  %00010000
 
                DECLE  %00010000
 
                DECLE  %01111100
 
                DECLE  %10111010
 
                DECLE  %10111010
 
                DECLE  %10111010
 
                DECLE  %10111010
 
                DECLE  %00111000
 
                DECLE  %00101000
 
                DECLE  %00101000
 
                DECLE  %00101000
 
                DECLE  %00101000
 
                DECLE  %01101100
 
    @@end:     
 
                ENDP
 
   
 
    ;; ======================================================================== ;;
 
    ;;  LIBRARY INCLUDES                                                        ;;
 
    ;; ======================================================================== ;;
 
                INCLUDE "print.asm"      ; PRINT.xxx routines
 
                INCLUDE "fillmem.asm"    ; CLRSCR/FILLZERO/FILLMEM
 
                INCLUDE "memcpy.asm"      ; MEMCPY
 
                INCLUDE "timer.asm"          ; Timer-based task stuff
 
                INCLUDE "taskq.asm"          ; RUNQ/QTASK
 
   
 
   
 
    ;* ======================================================================== *;
 
    ;*  This program is free software; you can redistribute it and/or modify    *;
 
    ;*  it under the terms of the GNU General Public License as published by    *;
 
    ;*  the Free Software Foundation; either version 2 of the License, or      *;
 
    ;*  (at your option) any later version.                                    *;
 
    ;*                                                                          *;
 
    ;*  This program is distributed in the hope that it will be useful,        *;
 
    ;*  but WITHOUT ANY WARRANTY; without even the implied warranty of          *;
 
    ;*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *;
 
    ;*  General Public License for more details.                                *;
 
    ;*                                                                          *;
 
    ;*  You should have received a copy of the GNU General Public License      *;
 
    ;*  along with this program; if not, write to the Free Software            *;
 
    ;*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              *;
 
    ;* ======================================================================== *;
 
    ;*                  Copyright (c) 2002, Joseph Zbiciak                    *;
 
    ;* ======================================================================== *;
 
  
 
= tag2b.asm =
 
= tag2b.asm =

Revision as of 13:31, 18 November 2011

tag2a.asm

This is the code for the first version built in the tutorial - the player graphic moves across the screen quite rapidly.

;;==========================================================================;;
;; Joe Zbiciak's Tagalong Todd!                                             ;;
;; Copyright 2002, Joe Zbiciak, intvnut AT gmail.com.                       ;;
;; http://spatula-city.org/~im14u2c/intv/                                   ;;
;;==========================================================================;;

;* ======================================================================== *;
;*  TO BUILD IN BIN+CFG FORMAT:                                             *;
;*      as1600 -o tagalong.bin -l tagalong.lst tagalong.asm                 *;
;*                                                                          *;
;*  TO BUILD IN ROM FORMAT:                                                 *;
;*      as1600 -o tagalong.rom -l tagalong.lst tagalong.asm                 *;
;* ======================================================================== *;

            ROMW    16              ; Use 16-bit ROM

;------------------------------------------------------------------------------
; Include system information
;------------------------------------------------------------------------------
            INCLUDE "gimini.asm"

;------------------------------------------------------------------------------
; Global constants and configuration.
;------------------------------------------------------------------------------

TSKQM       EQU     $7              ; Task queue is 8 entries large
MAXTSK      EQU     3               ; Only one task

;------------------------------------------------------------------------------
; Allocate 8-bit variables in Scratch RAM
;------------------------------------------------------------------------------
SCRATCH     ORG     $100, $100, "-RWBN"

ISRVEC      RMB     2               ; Always at $100 / $101

            ; Task-oriented 8-bit variables
TSKQHD      RMB     1               ; Task queue head
TSKQTL      RMB     1               ; Task queue tail
TSKDQ       RMB     2*(TSKQM+1)     ; Task data queue
TSKACT      RMB     1               ; Number of active tasks

_SCRATCH    EQU     $               ; end of scratch area



;------------------------------------------------------------------------------
; Allocate 16-bit variables in System RAM 
;------------------------------------------------------------------------------
SYSTEM      ORG     $2F0, $2F0, "-RWBN"
STACK       RMB     32              ; Reserve 32 words for the stack

            ; Task-oriented 16-bit variables
TSKQ        RMB     (TSKQM + 1)     ; Task queue
TSKTBL      RMB     (MAXTSK * 4)    ; Timer task table

            ; STIC shadow
STICSH      RMB     24              ; Room for X, Y, and A regs only.

PLYR        PROC
@@XP        RMB     1               ; X position
@@YP        RMB     1               ; Y position
            ENDP

MOB_BUSY    RMB     1
_SYSTEM     EQU     $               ; end of system area


;------------------------------------------------------------------------------
; EXEC-friendly ROM header.
;------------------------------------------------------------------------------
            ORG     $5000           ; Use default memory map
ROMHDR:     BIDECLE ZERO            ; MOB picture base   (points to NULL list)
            BIDECLE ZERO            ; Process table      (points to NULL list)
            BIDECLE MAIN            ; Program start address
            BIDECLE ZERO            ; Bkgnd picture base (points to NULL list)
            BIDECLE ONES            ; GRAM pictures      (points to NULL list)
            BIDECLE TITLE           ; Cartridge title/date
            DECLE   $03C0           ; No ECS title, run code after title,
                                    ; ... no clicks
ZERO:       DECLE   $0000           ; Screen border control
            DECLE   $0000           ; 0 = color stack, 1 = f/b mode
ONES:       DECLE   C_BLU, C_BLU    ; Initial color stack 0 and 1: Blue
            DECLE   C_BLU, C_BLU    ; Initial color stack 2 and 3: Blue
            DECLE   C_BLU           ; Initial border color: Blue
;------------------------------------------------------------------------------


;; ======================================================================== ;;
;;  TITLE  -- Display our modified title screen & copyright date.           ;;
;; ======================================================================== ;;
TITLE:      PROC
            STRING  102, "Tagalong Todd", 0
            BEGIN
          
            ; Patch the title string to say '=JRMZ=' instead of Mattel.
            CALL    PRINT.FLS       ; Write string (ptr in R5)
            DECLE   C_WHT, $23D     ; White, Point to 'Mattel' in top-left
            STRING  '=JRMZ='        ; Guess who?  :-)
            STRING  ' Productions' 
            BYTE    0
          
            CALL    PRINT.FLS       ; Write string (ptr in R1)
            DECLE   C_WHT, $2D0     ; White, Point to 'Mattel' in lower-right
            STRING  '2002 =JRMZ='   ; Guess who?  :-)
            BYTE    0
          
            ; Done.
            RETURN                  ; Return to EXEC for title screen display
            ENDP


;; ======================================================================== ;;
;;  MAIN:  Here's our main program code.                                    ;;
;; ======================================================================== ;;
MAIN:       PROC
            DIS
            MVII    #STACK, R6      ; Set up our stack

            MVII    #$25E,  R1      ;\
            MVII    #$102,  R4      ; |-- Clear all of RAM memory
            CALL    FILLZERO        ;/

            MVII    #INITISR, R0    ;\    Do GRAM initialization in ISR.
            MVO     R0,     ISRVEC  ; |__ INITISR will the point to the 
            SWAP    R0              ; |   regular ISR when it's done.
            MVO     R0,     ISRVEC+1;/    

            ;; ------------------------------------------------------------ ;;
            ;;  Put the character on the screen                             ;;
            ;; ------------------------------------------------------------ ;;
            MVII    #$1000, R0
            MVO     R0,     PLYR.XP
            MVO     R0,     PLYR.YP

            EIS

            ;; ------------------------------------------------------------ ;;
            ;;  Fall into the RUNQ.  We should never exit the RUNQ in this  ;;
            ;;  demo, since we never call SCHEDEXIT.                        ;;
            ;; ------------------------------------------------------------ ;;
            CALL    RUNQ            ; Run until a SCHEDEXIT happens

            ;; ------------------------------------------------------------ ;;
            ;;  If a SCHEDEXIT *does* happen (say, due to a bug), crash     ;;
            ;;  gracefully.                                                 ;;
            ;; ------------------------------------------------------------ ;;
            CALL    PRINT.FLS
            DECLE   C_RED, $200 + 11*20
                    ;01234567890123456789
            STRING  "SCHEDEXIT WAS CALLED",0

            DECR    PC              ; Can't get here
          
            ENDP

;; ======================================================================== ;;
;;  MOB_UPDATE -- This updates the player's position                        ;;
;; ======================================================================== ;;
MOB_UPDATE  PROC
            PSHR    R5

            ;; ------------------------------------------------------------ ;;
            ;;  Merge our position with our MOB registers.                  ;;
            ;; ------------------------------------------------------------ ;;
            MVII    #@@mobr,    R4      ; MOB information template
            MVII    #STICSH,    R5

            MVI     PLYR.XP,    R0      ;\
            SWAP    R0                  ; |
            ANDI    #$00FF,     R0      ; |- Player X position
            XOR@    R4,         R0      ; |
            MVO@    R0,         R5      ;/
          
            ADDI    #7,         R5      ;  Move pointer to Y coordinate section of the STICSH
            
            MVI     PLYR.YP,    R0      ;\
            SWAP    R0                  ; |
            ANDI    #$007F,     R0      ; |- Player Y position
            XOR@    R4,         R0      ; |
            MVO@    R0,         R5      ;/

            ADDI    #7,         R5      ; Move pointer to A register section of the STICSH

            MVI@    R4,         R0      ; \_ Player's A register
            MVO@    R0,         R5      ; /

            CLRR    R0
            MVO     R0,         MOB_BUSY

            PULR    PC

            ;; ------------------------------------------------------------ ;;
            ;;  Bits to copy into MOB registers.                            ;;
            ;; ------------------------------------------------------------ ;;
@@mobr      DECLE   STIC.mobx_visb      ; make player visible
            DECLE   STIC.moby_yres      ; make player 8x16 MOB
            DECLE   STIC.moba_fg1 + STIC.moba_gram + 0*8    ; Player is blue
            ENDP
    

;; ======================================================================== ;;
;;  ISR -- Just keep the screen on, and copy the STIC shadow over.          ;;
;; ======================================================================== ;;
ISR         PROC

            ;; ------------------------------------------------------------ ;;
            ;;  Basics:  Update color stack and video enable.               ;;
            ;; ------------------------------------------------------------ ;;
            MVO     R0,     STIC.viden  ; Enable display
            MVI     STIC.mode, R0       ; ...in color-stack mode

            MVII    #C_GRY, R0          ;\
            MVO     R0,     STIC.cs0    ; |__ Set display to grey
            MVO     R0,     STIC.cs2    ; |
            MVO     R0,     STIC.bord   ;/

            ;; ------------------------------------------------------------ ;;
            ;;  Update STIC shadow and queue updates for MOB velocities.    ;;
            ;; ------------------------------------------------------------ ;;
            MVI     MOB_BUSY, R0
            TSTR    R0
            BNEQ    @@no_mobs
            MVO     PC,     MOB_BUSY


            CALL    MEMCPY              ;\__ Copy over the STIC shadow.
            DECLE   $0000, STICSH, 24   ;/

            MVII    #MOB_UPDATE, R0
            JSRD    R5,   QTASK

            MVII    #MOVE_PLAYER, R0
            JSRD    R5,   QTASK

@@no_mobs:  

            CALL    DOTIMER             ; Update timer-based tasks.
            B       $1014               ; return from interrupt.
            ENDP


;; ======================================================================== ;;
;;  MOVE_PLAYER -- Just programatically move the player around a bit.       ;;
;; ======================================================================== ;;
MOVE_PLAYER PROC
            PSHR    R5

            ; Just for something to do we'll move across the screen, then 
            ; down a row and back across, again and again until we get to the 
            ; bottom at which time we'll start over

            MVI     PLYR.XP,    R0      ;\
            SWAP    R0                  ; >-- Get player X position
            ANDI    #$00FF,     R0      ;/

            ADDI    #8,         R0      ; move 8 X positions to the right

            MVII    #159,       R1      ;\__ compare X against the right edge of the screen
            CMPR    R0,         R1      ;/
            BLT     @@fixx

            SWAP    R0                  ; put the integer part back into the upper byte
            MVO     R0,    PLYR.XP      ; update the X position
            B       @@done              ; we're done

            ; here we've hit the right edge of the screen and should move down a row
@@fixx      MVII    #0,         R0      ;\__ set X position back to zero
            MVO     R0,    PLYR.XP      ;/

            MVI     PLYR.YP,    R0      ;\
            SWAP    R0                  ; >-- Get player Y position
            ANDI    #$007F,     R0      ;/

            ADDI    #8,         R0      ;  move 8 Y positions down

            MVII    #96,        R1      ;\__ compare Y against the bottom edge of the screen
            CMPR    R0,         R1      ;/
            BLT     @@fixy

            SWAP    R0                  ; put the integer part back into the upper byte
            MVO     R0,    PLYR.YP      ; update the Y position
            B       @@done
            
            ; here we've hit the bottom edge of the screen and should move to the top
@@fixy      MVII    #0,         R0      ;\__ set Y position back to zero
            MVO     R0,    PLYR.YP      ;/

@@done      PULR    PC
            ENDP

;; ======================================================================== ;;
;;  INITISR -- Copy our GRAM image over, and then do the plain ISR.         ;;
;; ======================================================================== ;;
INITISR     PROC
            PSHR    R5

            CALL    MEMCPY
            DECLE   $3800, GRAMIMG, GRAMIMG.end - GRAMIMG

            MVII    #ISR,   R0
            MVO     R0,     ISRVEC
            SWAP    R0
            MVO     R0,     ISRVEC + 1

            PULR    PC
            ENDP

;; ======================================================================== ;;
;;  GRAMIMG -- Arrow pictures and other graphics to load into GRAM.         ;;
;; ======================================================================== ;;
GRAMIMG     PROC

@@person:   ; Crappy person graphic.
            DECLE   %00010000
            DECLE   %00111000
            DECLE   %00111000
            DECLE   %00010000
            DECLE   %00010000
            DECLE   %01111100
            DECLE   %10111010
            DECLE   %10111010
            DECLE   %10111010
            DECLE   %10111010
            DECLE   %00111000
            DECLE   %00101000
            DECLE   %00101000
            DECLE   %00101000
            DECLE   %00101000
            DECLE   %01101100
@@end:      
            ENDP

;; ======================================================================== ;;
;;  LIBRARY INCLUDES                                                        ;;
;; ======================================================================== ;;
            INCLUDE "print.asm"       ; PRINT.xxx routines
            INCLUDE "fillmem.asm"     ; CLRSCR/FILLZERO/FILLMEM
            INCLUDE "memcpy.asm"      ; MEMCPY
            INCLUDE "timer.asm"          ; Timer-based task stuff
            INCLUDE "taskq.asm"          ; RUNQ/QTASK


;* ======================================================================== *;
;*  This program is free software; you can redistribute it and/or modify    *;
;*  it under the terms of the GNU General Public License as published by    *;
;*  the Free Software Foundation; either version 2 of the License, or       *;
;*  (at your option) any later version.                                     *;
;*                                                                          *;
;*  This program is distributed in the hope that it will be useful,         *;
;*  but WITHOUT ANY WARRANTY; without even the implied warranty of          *;
;*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *;
;*  General Public License for more details.                                *;
;*                                                                          *;
;*  You should have received a copy of the GNU General Public License       *;
;*  along with this program; if not, write to the Free Software             *;
;*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               *;
;* ======================================================================== *;
;*                   Copyright (c) 2002, Joseph Zbiciak                     *;
;* ======================================================================== *;

tag2b.asm

This is the code for the second version built in the tutorial - the player graphic moves across the screen at a much more reasonable pace.

   ;;==========================================================================;;
   ;; Joe Zbiciak's Tagalong Todd!                                             ;;
   ;; Copyright 2002, Joe Zbiciak, intvnut AT gmail.com.                       ;;
   ;; http://spatula-city.org/~im14u2c/intv/                                   ;;
   ;;==========================================================================;;
   
   ;* ======================================================================== *;
   ;*  TO BUILD IN BIN+CFG FORMAT:                                             *;
   ;*      as1600 -o tagalong.bin -l tagalong.lst tagalong.asm                 *;
   ;*                                                                          *;
   ;*  TO BUILD IN ROM FORMAT:                                                 *;
   ;*      as1600 -o tagalong.rom -l tagalong.lst tagalong.asm                 *;
   ;* ======================================================================== *;
   
               ROMW    16              ; Use 16-bit ROM
   
   ;------------------------------------------------------------------------------
   ; Include system information
   ;------------------------------------------------------------------------------
               INCLUDE "gimini.asm"
   
   ;------------------------------------------------------------------------------
   ; Global constants and configuration.
   ;------------------------------------------------------------------------------
   
   TSKQM       EQU     $7              ; Task queue is 8 entries large
   MAXTSK      EQU     3               ; Only one task
   
   ;------------------------------------------------------------------------------
   ; Allocate 8-bit variables in Scratch RAM
   ;------------------------------------------------------------------------------
   SCRATCH     ORG     $100, $100, "-RWBN"
   
   ISRVEC      RMB     2               ; Always at $100 / $101
   
               ; Task-oriented 8-bit variables
   TSKQHD      RMB     1               ; Task queue head
   TSKQTL      RMB     1               ; Task queue tail
   TSKDQ       RMB     2*(TSKQM+1)     ; Task data queue
   TSKACT      RMB     1               ; Number of active tasks
   
   _SCRATCH    EQU     $               ; end of scratch area
   
   
   
   ;------------------------------------------------------------------------------
   ; Allocate 16-bit variables in System RAM 
   ;------------------------------------------------------------------------------
   SYSTEM      ORG     $2F0, $2F0, "-RWBN"
   STACK       RMB     32              ; Reserve 32 words for the stack
   
               ; Task-oriented 16-bit variables
   TSKQ        RMB     (TSKQM + 1)     ; Task queue
   TSKTBL      RMB     (MAXTSK * 4)    ; Timer task table
   
               ; STIC shadow
   STICSH      RMB     24              ; Room for X, Y, and A regs only.
   
   PLYR        PROC
   @@XP        RMB     1               ; X position
   @@YP        RMB     1               ; Y position
               ENDP
   
   MOB_BUSY    RMB     1
   _SYSTEM     EQU     $               ; end of system area
   
   
   ;------------------------------------------------------------------------------
   ; EXEC-friendly ROM header.
   ;------------------------------------------------------------------------------
               ORG     $5000           ; Use default memory map
   ROMHDR:     BIDECLE ZERO            ; MOB picture base   (points to NULL list)
               BIDECLE ZERO            ; Process table      (points to NULL list)
               BIDECLE MAIN            ; Program start address
               BIDECLE ZERO            ; Bkgnd picture base (points to NULL list)
               BIDECLE ONES            ; GRAM pictures      (points to NULL list)
               BIDECLE TITLE           ; Cartridge title/date
               DECLE   $03C0           ; No ECS title, run code after title,
                                       ; ... no clicks
   ZERO:       DECLE   $0000           ; Screen border control
               DECLE   $0000           ; 0 = color stack, 1 = f/b mode
   ONES:       DECLE   C_BLU, C_BLU    ; Initial color stack 0 and 1: Blue
               DECLE   C_BLU, C_BLU    ; Initial color stack 2 and 3: Blue
               DECLE   C_BLU           ; Initial border color: Blue
   ;------------------------------------------------------------------------------
   
   
   ;; ======================================================================== ;;
   ;;  TITLE  -- Display our modified title screen & copyright date.           ;;
   ;; ======================================================================== ;;
   TITLE:      PROC
               STRING  102, "Tagalong Todd", 0
               BEGIN
             
               ; Patch the title string to say '=JRMZ=' instead of Mattel.
               CALL    PRINT.FLS       ; Write string (ptr in R5)
               DECLE   C_WHT, $23D     ; White, Point to 'Mattel' in top-left
               STRING  '=JRMZ='        ; Guess who?  :-)
               STRING  ' Productions' 
               BYTE    0
             
               CALL    PRINT.FLS       ; Write string (ptr in R1)
               DECLE   C_WHT, $2D0     ; White, Point to 'Mattel' in lower-right
               STRING  '2002 =JRMZ='   ; Guess who?  :-)
               BYTE    0
             
               ; Done.
               RETURN                  ; Return to EXEC for title screen display
               ENDP
   
   
   ;; ======================================================================== ;;
   ;;  MAIN:  Here's our main program code.                                    ;;
   ;; ======================================================================== ;;
   MAIN:       PROC
               DIS
               MVII    #STACK, R6      ; Set up our stack
   
               MVII    #$25E,  R1      ;\
               MVII    #$102,  R4      ; |-- Clear all of RAM memory
               CALL    FILLZERO        ;/
   
               MVII    #INITISR, R0    ;\    Do GRAM initialization in ISR.
               MVO     R0,     ISRVEC  ; |__ INITISR will the point to the 
               SWAP    R0              ; |   regular ISR when it's done.
               MVO     R0,     ISRVEC+1;/    
   
   
               ;; ------------------------------------------------------------ ;;
               ;;  Set up character movement task                              ;;
               ;; ------------------------------------------------------------ ;;
               CALL    STARTTASK
               DECLE   0
               DECLE   MOVE_PLAYER
               DECLE   30, 30          ; 4Hz
   
               MVII    #1,     R0
               MVO     R0,     TSKACT
   
               ;; ------------------------------------------------------------ ;;
               ;;  Put the character on the screen                             ;;
               ;; ------------------------------------------------------------ ;;
               MVII    #$1000, R0
               MVO     R0,     PLYR.XP
               MVO     R0,     PLYR.YP
   
               EIS
   
               ;; ------------------------------------------------------------ ;;
               ;;  Fall into the RUNQ.  We should never exit the RUNQ in this  ;;
               ;;  demo, since we never call SCHEDEXIT.                        ;;
               ;; ------------------------------------------------------------ ;;
               CALL    RUNQ            ; Run until a SCHEDEXIT happens
   
               ;; ------------------------------------------------------------ ;;
               ;;  If a SCHEDEXIT *does* happen (say, due to a bug), crash     ;;
               ;;  gracefully.                                                 ;;
               ;; ------------------------------------------------------------ ;;
               CALL    PRINT.FLS
               DECLE   C_RED, $200 + 11*20
                       ;01234567890123456789
               STRING  "SCHEDEXIT WAS CALLED",0
   
               DECR    PC              ; Can't get here
             
               ENDP
   
   ;; ======================================================================== ;;
   ;;  MOB_UPDATE -- This updates the player's position                        ;;
   ;; ======================================================================== ;;
   MOB_UPDATE  PROC
               PSHR    R5
   
               ;; ------------------------------------------------------------ ;;
               ;;  Merge our position with our MOB registers.                  ;;
               ;; ------------------------------------------------------------ ;;
               MVII    #@@mobr,    R4      ; MOB information template
               MVII    #STICSH,    R5
   
               MVI     PLYR.XP,    R0      ;\
               SWAP    R0                  ; |
               ANDI    #$00FF,     R0      ; |- Player X position
               XOR@    R4,         R0      ; |
               MVO@    R0,         R5      ;/
             
               ADDI    #7,         R5      ;  Move pointer to Y coordinate section of the STICSH
               
               MVI     PLYR.YP,    R0      ;\
               SWAP    R0                  ; |
               ANDI    #$007F,     R0      ; |- Player Y position
               XOR@    R4,         R0      ; |
               MVO@    R0,         R5      ;/
   
               ADDI    #7,         R5      ; Move pointer to A register section of the STICSH
   
               MVI@    R4,         R0      ; \_ Player's A register
               MVO@    R0,         R5      ; /
   
               CLRR    R0
               MVO     R0,         MOB_BUSY
   
               PULR    PC
   
               ;; ------------------------------------------------------------ ;;
               ;;  Bits to copy into MOB registers.                            ;;
               ;; ------------------------------------------------------------ ;;
   @@mobr      DECLE   STIC.mobx_visb      ; make player visible
               DECLE   STIC.moby_yres      ; make player 8x16 MOB
               DECLE   STIC.moba_fg1 + STIC.moba_gram + 0*8    ; Player is blue
               ENDP
       
   
   ;; ======================================================================== ;;
   ;;  ISR -- Just keep the screen on, and copy the STIC shadow over.          ;;
   ;; ======================================================================== ;;
   ISR         PROC
   
               ;; ------------------------------------------------------------ ;;
               ;;  Basics:  Update color stack and video enable.               ;;
               ;; ------------------------------------------------------------ ;;
               MVO     R0,     STIC.viden  ; Enable display
               MVI     STIC.mode, R0       ; ...in color-stack mode
   
               MVII    #C_GRY, R0          ;\
               MVO     R0,     STIC.cs0    ; |__ Set display to grey
               MVO     R0,     STIC.cs2    ; |
               MVO     R0,     STIC.bord   ;/
   
               ;; ------------------------------------------------------------ ;;
               ;;  Update STIC shadow and queue updates for MOB velocities.    ;;
               ;; ------------------------------------------------------------ ;;
               MVI     MOB_BUSY, R0
               TSTR    R0
               BNEQ    @@no_mobs
               MVO     PC,     MOB_BUSY
   
   
               CALL    MEMCPY              ;\__ Copy over the STIC shadow.
               DECLE   $0000, STICSH, 24   ;/
   
               MVII    #MOB_UPDATE, R0
               JSRD    R5,   QTASK
   
   @@no_mobs:  
   
               CALL    DOTIMER             ; Update timer-based tasks.
               B       $1014               ; return from interrupt.
               ENDP
   
   ;; ======================================================================== ;;
   ;;  MOVE_PLAYER -- Just programatically move the player around a bit.       ;;
   ;; ======================================================================== ;;
   MOVE_PLAYER PROC
               PSHR    R5
   
               ; Just for something to do we'll move across the screen, then 
               ; down a row and back across, again and again until we get to the 
               ; bottom at which time we'll start over
   
               MVI     PLYR.XP,    R0      ;\
               SWAP    R0                  ; >-- Get player X position
               ANDI    #$00FF,     R0      ;/
   
               ADDI    #8,         R0      ; move 8 X positions to the right
   
               MVII    #159,       R1      ;\__ compare X against the right edge of the screen
               CMPR    R0,         R1      ;/
               BLT     @@fixx
   
               SWAP    R0                  ; put the integer part back into the upper byte
               MVO     R0,    PLYR.XP      ; update the X position
               B       @@done              ; we're done
   
               ; here we've hit the right edge of the screen and should move down a row
   @@fixx      MVII    #0,         R0      ;\__ set X position back to zero
               MVO     R0,    PLYR.XP      ;/
   
               MVI     PLYR.YP,    R0      ;\
               SWAP    R0                  ; >-- Get player Y position
               ANDI    #$007F,     R0      ;/
   
               ADDI    #8,         R0      ;  move 8 Y positions down
   
               MVII    #96,        R1      ;\__ compare Y against the bottom edge of the screen
               CMPR    R0,         R1      ;/
               BLT     @@fixy
   
               SWAP    R0                  ; put the integer part back into the upper byte
               MVO     R0,    PLYR.YP      ; update the Y position
               B       @@done
               
               ; here we've hit the bottom edge of the screen and should move to the top
   @@fixy      MVII    #0,         R0      ;\__ set Y position back to zero
               MVO     R0,    PLYR.YP      ;/
   
   @@done      PULR    PC
               ENDP
   
   ;; ======================================================================== ;;
   ;;  INITISR -- Copy our GRAM image over, and then do the plain ISR.         ;;
   ;; ======================================================================== ;;
   INITISR     PROC
               PSHR    R5
   
               CALL    MEMCPY
               DECLE   $3800, GRAMIMG, GRAMIMG.end - GRAMIMG
   
               MVII    #ISR,   R0
               MVO     R0,     ISRVEC
               SWAP    R0
               MVO     R0,     ISRVEC + 1
   
               PULR    PC
               ENDP
   
   ;; ======================================================================== ;;
   ;;  GRAMIMG -- Arrow pictures and other graphics to load into GRAM.         ;;
   ;; ======================================================================== ;;
   GRAMIMG     PROC
   
   @@person:   ; Crappy person graphic.
               DECLE   %00010000
               DECLE   %00111000
               DECLE   %00111000
               DECLE   %00010000
               DECLE   %00010000
               DECLE   %01111100
               DECLE   %10111010
               DECLE   %10111010
               DECLE   %10111010
               DECLE   %10111010
               DECLE   %00111000
               DECLE   %00101000
               DECLE   %00101000
               DECLE   %00101000
               DECLE   %00101000
               DECLE   %01101100
   @@end:      
               ENDP
   
   ;; ======================================================================== ;;
   ;;  LIBRARY INCLUDES                                                        ;;
   ;; ======================================================================== ;;
               INCLUDE "print.asm"       ; PRINT.xxx routines
               INCLUDE "fillmem.asm"     ; CLRSCR/FILLZERO/FILLMEM
               INCLUDE "memcpy.asm"      ; MEMCPY
               INCLUDE "timer.asm"          ; Timer-based task stuff
               INCLUDE "taskq.asm"          ; RUNQ/QTASK
   
   
   ;* ======================================================================== *;
   ;*  This program is free software; you can redistribute it and/or modify    *;
   ;*  it under the terms of the GNU General Public License as published by    *;
   ;*  the Free Software Foundation; either version 2 of the License, or       *;
   ;*  (at your option) any later version.                                     *;
   ;*                                                                          *;
   ;*  This program is distributed in the hope that it will be useful,         *;
   ;*  but WITHOUT ANY WARRANTY; without even the implied warranty of          *;
   ;*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *;
   ;*  General Public License for more details.                                *;
   ;*                                                                          *;
   ;*  You should have received a copy of the GNU General Public License       *;
   ;*  along with this program; if not, write to the Free Software             *;
   ;*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               *;
   ;* ======================================================================== *;
   ;*                   Copyright (c) 2002, Joseph Zbiciak                     *;
   ;* ======================================================================== *;