smashtv/HSTD.ASM

1865 lines
69 KiB
NASM
Raw Normal View History

2021-04-06 15:09:56 -07:00
.FILE 'HSTD.ASM'
.TITLE "ROBO HIGH-SCORE-TO-DATE MANAGEMENT"
.WIDTH 132
.OPTION B,D,L,T
.MNOLIST
;
; SOFTWARE: LARRY DeMAR, ROBBI ASHWORTH, EUGENE JARVIS
;
; COPYRIGHT (C) 1990 WILLIAMS ELECTRONICS GAMES, INC.
;
;
; GET THE SYSTEM STUFF
.INCLUDE "MPROC.EQU" ;MPROC EQUATES
.INCLUDE "DISP.EQU" ;DISPLAY PROC. EQUATES
.INCLUDE "\VIDEO\SYS\SYS.INC" ;Z UNIT SYSTEM EQUATES
.INCLUDE "\VIDEO\SYS\MACROS.HDR" ;MACROS DEFINITIONS
.INCLUDE "ROBO.EQU"
.INCLUDE "IMGTBL.GLO"
.INCLUDE "LINK.EQU" ;LINKY EQUATES
.TEXT
*
* IN THIS MODULE
*
.DEF GET_HSCR
.DEF RC_BYTEI
.DEF RC_BYTE
.DEF RC_WORD
.DEF RC_LONG
.DEF RC_LONGI
.DEF WC_BYTE
.DEF WC_BYTEI
.DEF WC_WORD
.DEF WC_WORDI
.DEF WC_LONG
.DEF WC_LONGI
.DEF PT_ENTRY
.DEF INIT_TB
.DEF INIT_TAB ;GEORGES POWER UP ENTRY
.DEF P_FORK
.DEF VAL_TAB
.DEF ROM_PTRS
.DEF ALL_TAB
.DEF TOD_TAB
.DEF ISHSTD,GETINIT,GETINIT1,GETINIT2,INITTIM
.DEF SET_PAGE
.DEF A2_CHECK
.DEF DEC_HSR,INIT_HSR,GET_HSC
.DEF GETHIGH
*
* OTHER MODULES
*
.REF RD15FONT,SYSCOPY,P1DATA,P2DATA,DELPAL,GPALOBJ
.REF BINBCD
.REF AFONT0,GOGO
*
* HELP.ASM
*
.REF DEF_PAGE,GET_ADJ
.TEXT
**************************************************************************
* *
* HIGH SCORE TABLE DEFINITIONS *
* *
**************************************************************************
ALL_TAB:
.LONG ALL_TIME_ORIGIN ;LOCATION OF TABLE
.WORD ALL_TIME_ENTRIES-1 ;NUMBER IN THE TABLE (DON'T COUNT ZERO FILLER)
.WORD ALL_TIME_VISIBLE ;# VISIBLE (SHOW 20 ALL TIME)
.WORD ALL_TIME_SELECT ;BITS TO SELECT IT
.LONG ALL_TIME_ROM_TABLE ;ROM IMAGE OF TABLE
.WORD ALL_TIME_ENTRIES/5 ;RESET TABLE IF 1/5 OR MORE BAD
TOD_TAB:
.LONG TODAYS_ORIGIN ;LOCATION OF TABLE
.WORD TODAYS_ENTRIES-1 ;NUMBER IN THE TABLE (DON'T COUNT ZERO FILLER)
.WORD TODAYS_VISIBLE ;# VISIBLE (SHOW 20 ALL TIME)
.WORD TODAYS_SELECT ;BITS TO SELECT IT
.LONG TODAYS_ROM_TABLE ;ROM IMAGE OF TABLE
.WORD TODAYS_ENTRIES/5 ;RESET TABLE IF 1/5 OR MORE BAD
P_FORK:
MMTM SP,A1
MOVE *A13(PROCID),A1,W ;PASS OUR ID TO FORKED PROCESS
CALLA GETPRC ;MAKE THE PROCESS
MMFM SP,A1
RETS
**************************************************************************
* *
* AUTO HIGH SCORE TABLE RESET HANDLING *
* *
**************************************************************************
* *
* DEC_HSR *
* *
* THIS IS CALLED WITH EACH START OR CONTINUE FOR *
* A PLAYER. IT REMOVES 1 FROM THE HSTD COUNTER UNLESS *
* ITS ALREADY SITTING AT ZERO. *
* *
**************************************************************************
DEC_HSR:
MMTM SP,A0
CALLR GET_HSC ;THIS IS EASY...GET THE COUNTER
JRZ DECHX ;ITS ZERO....NO ACTION.
DEC A0 ;REMOVE A TICK
CALLR PUT_HSC ;PUT IT BACK JAK
DECHX:
MMFM SP,A0
RETS
**************************************************************************
* *
* DELAY_HSRESET *
* *
* THIS IS CALLED WHEN A NEW ENTRY IS MADE IN THE ALL TIME *
* HIGH SCORE TABLE. IF WE'RE CLOSE TO A HIGH SCORE *
* RESET, WE PUT IT OFF AWHILE SO HE CAN SHOW HIS FRIENDS *
* FOR A FEW DAYS. *
* *
**************************************************************************
HS_MIN EQU 750 ;ALWAYS 750 PLAYS BEFORE REMOVING A FRESH
* ;NAME.
DELAY_HSRESET:
MMTM SP,A0
CALLR GET_HSC ;THIS IS EASY...GET THE COUNTER
CMPI HS_MIN,A0 ;IS IT TOO LOW
JRHS DHX ;NOPE...NO ACTION
MOVI HS_MIN,A0 ;STOP THE RESET!
CALLR PUT_HSC ;THIS MANY PLAYS TILL RESET!
DHX:
MMFM SP,A0
RETS
**************************************************************************
* *
* INIT_HSR *
* *
* THIS IS CALLED TO INITIALIZE THE HIGH SCORE RESET *
* COUNTER TO ITS ADJUSTED VALUE. *
* *
**************************************************************************
INIT_HSR:
MMTM SP,A0
MOVI ADJHSRES,A0
CALLA GET_ADJ ;GET THE ADJUSTED VALUE
CALLR PUT_HSC ;SET IT TO THIS VALUE
MMFM SP,A0
RETS
**************************************************************************
* *
* PUT_HSC *
* *
* THIS IS CALLED TO SET THE HIGH SCORE RESET COUNTER *
* TO THE VALUE IN A0. *
* *
**************************************************************************
PUT_HSC:
MMTM SP,A7,A0
CALLR HSR_PAGE ;HIGH SCORE PAGE
MOVI HRESET_COUNTER,A7 ;POINT AT
CALLR WC_LONGI ;WRITE OUR PARAMETER
NOT A0 ;NEGATE IT.
CALLR WC_LONG ;AND WRITE IN SUBSEQUENT SPOT.
CALLA DEF_PAGE ;FLIP PAGE
MMFM SP,A7,A0 ;AND RETURN
RETS
**************************************************************************
* *
* GET_HSC *
* *
* THIS IS CALLED TO FETCH THE HIGH SCORE COUNTER IN A0. *
* IF IT IS INVALID, IT WILL IMMEDIATELY BE RESET TO THE *
* ADJUSTED VALUE AND THIS IS WHAT WILL BE RETURNED *
* IN A0. .EQ. MEANS ITS AT ZERO! *
* *
**************************************************************************
GET_HSC:
MMTM SP,A7,A1
CALLR HSR_PAGE ;POINT PAGE AT HSR
MOVI HRESET_COUNTER,A7 ;POINT AT
CALLR RC_LONGI ;READ THE VALUE
MOVE A0,A1 ;STASH IT
CALLR RC_LONG ;READ VERIFIER
NOT A0 ;SEE IF ITS VALID
CMP A0,A1
JRZ GET_HSCX ;IT IS....RETURN IT.
CALLR INIT_HSR ;REFRESH IT WITH FACTORY VALUE
*
* NOW RETURN THE FACTORY VALUE IN CASE IT DIDN'T TAKE
*
MOVI ADJHSRES,A0
CALLA GET_ADJ ;GET THE ADJUSTED VALUE
GET_HSCX:
CALLA DEF_PAGE ;FLIP PAGE AWAY FROM US
MOVE A0,A0 ;SET Z FLAG BASED ON COUNTER
MMFM SP,A7,A1
RETS
HSR_PAGE:
MMTM SP,A1
MOVI HSR_SELECT,A1
CALLR SET_PAGE
MMFM SP,A1
RETS
**********************************************************************
*
*DISPLAY HIGH SCORE TABLE
*
**********************************************************************
GETHIGH
MOVI ALL_TIME_SELECT,A1 ;BITS TO SELECT IT
CALLR SET_PAGE
MOVI >3A0065,A10 ;SCREEN START ADDRESS
MOVI ALL_TIME_ORIGIN+HS_SCORE+HS_SIZE,A7 ;TABLE START ADDRESS
CALLR HSNUMDSP
MOVI >380031,A10 ;SCREEN START ADDRESS
MOVI ALL_TIME_ORIGIN+HS_INITS+HS_SIZE,A7 ;TABLE START ADDRESS
CALLR HSINITDSP
MOVI TODAYS_SELECT,A1 ;BITS TO SELECT IT
CALLR SET_PAGE
MOVI >3A0123,A10 ;SCREEN START ADDRESS
MOVI TODAYS_ORIGIN+HS_SCORE+HS_SIZE,A7 ;TABLE START ADDRESS
CALLR HSNUMDSP
MOVI >3800EE,A10 ;SCREEN START ADDRESS
MOVI TODAYS_ORIGIN+HS_INITS+HS_SIZE,A7 ;TABLE START ADDRESS
CALLR HSINITDSP
RETS
*
*DISPLAY SCORE TABLE SCORES IN ATTRACT
*A7=TABLE INDEX
*A10=DISPLAY COORD
*
HSNUMDSP
MMTM SP,A0,A1,A3,A5,A6,A7,A8,A10,A12
MOVK 10,A11 ;START WITH SCORE 1
HSDSPLL
MOVK 8,A12
CALLR RC_LONG ;GET THE FUCKING SCORE=A0
MOVE A10,A3 ;DEST Y:X
CLR A6 ;BLANKING FLAG
CALLR HSNUML0
ADDI >100000,A10 ;ADD VERT FOR NEXT LINE
ADDI HS_SIZE,A7
DSJS A11,HSDSPLL
MMFM SP,A0,A1,A3,A5,A6,A7,A8,A10,A12
RETS
*
*A0=NUMBER
*A3=Y:X
*A12=NUMBER OF DIGITS
*A6=BLANK FLAG
*
HSNUML0
MMTM SP,A0,A1,A2,A3,A4,A5
HSNUML00
MOVE A0,A1
SRL 28,A1 ;NEXT DIGIT VALUE INTO LOWEST 4 BITS
JRNE HSNUML1
MOVE A6,A6
JREQ HSNUML2 ;SKIP DIGIT IF BLANKING
HSNUML1
CMPI 9,A1 ;BAD DIGIT?
JRLS HSNUML10 ;NOPE...
MOVK 9,A1 ;OUTPUT 9 ON AN ERROR
HSNUML10
MOVK 1,A6
SLL 7,A1 ;*128 (NEXT HEADER PLEASE!!)
ADDI AFONT0,A1 ;BASE ADDRESS OF IMAGE HEADER
MOVE *A1,A2,L ;GET SIZE
MOVE *A1(>40),A4,L ;GET SAG
MOVI >0101,A1
MOVI DMAWNZ,A5
CALLA QDMAN
HSNUML2
ADDI 11,A3 ;STEP TO NEXT
SLL 4,A0 ;NEXT DIGIT
DSJS A12,HSNUML00
MMFM SP,A0,A1,A2,A3,A4,A5
RETS
*
*DISPLAY SCORE TABLE INITIALS IN ATTRACT
*A7=TABLE INDEX
*A10=DISPLAY COORD
*
HSINITDSP
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A10,A11,A12
MOVK 10,A11 ;START WITH SCORE 1
HSINTLL
MOVK 3,A12
MOVE A10,A3 ;GET DAG
SUBI HS_INITS,A7
CALLR RC_LONG ;GET THE FUCKING SCORE=A0
MOVE A0,A2 ;MOVE TO A2
ADDI HS_INITS,A7
HSINTL0
CALLR RC_BYTE ;GET INITIALS
ADDK 16,A7 ;STEP TO NEXT INITIAL
MOVI >3E3E0000,A1 ;FLASH IF INITS MATCH SCORE
CALLR A2_CHECK
JREQ HSINTL00
MOVI >27270000,A1 ;COLOR:PALETTE
HSINTL00
CALLR INITOUT ;OUTPUT INITIAL
DSJS A12,HSINTL0
ADDI >100000,A10 ;NEXT SPOT ON SCREEN
ADDI HS_SIZE-48,A7 ;GET NEXT GUY IN CMOS
DSJ A11,HSINTLL
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A10,A11,A12
RETS
*
*OUTPUT INITIAL RD15FONT
*A0=ASCII
*A1=COLOR:PALETTE
*A3=COORD
*
INITOUT
MMTM SP,A2,A4,A5
CMPI >7D,A0
JRHI INITERR
SUBI 21H,A0 ;ADJUST TABLE BOGOSITY
JRNN HSINTL01
INITERR ;BOGUS INITIAL SKIP IT
MOVK 8,A2
JRUC HSINTL02
HSINTL01
SLL 5,A0
ADDI RD15FONT,A0
MOVE *A0,A0,L ;GET POINTER
MOVE *A0,A2,L ;GET SIZE
MOVE *A0(>40),A4,L ;GET SAG
MOVI DMACNZ,A5
CALLA QDMAN
ZEXT A2,W ;ADD CHARACTER WIDTH
ADDK 2,A2
HSINTL02
ADD A2,A3
MMFM SP,A2,A4,A5
RETS
**************************************************************************
* *
* HIGH LEVEL HSTD ROUTINES *
* *
**************************************************************************
;TEN_X EQU 0F00000H
;ONE_O_X EQU 0F40000H
;ONE_X EQU 0FE0000H
;
;TIMER_TENS:
; .LONG 0,0,TEN_X,1500000H ;XV, YV, XP, YP
; .WORD 0,30 ;Z VEL 10....Z POS 0
; .LONG NO_IMG,1,0 ;IMG, Z SIZE, COLLISION VECT
; .WORD DMACNZ,5 ;WRITE NON-ZERO CONSTANT, OBJECT ID
; .LONG 0 ;NO SCANNER BLIP
;
;TIMER_UNITS:
; .LONG 0,0,ONE_X,1500000H ;XV, YV, XP, YP
; .WORD 0,30 ;Z VEL 10....Z POS 0
; .LONG NO_IMG,1,0 ;IMG, Z SIZE, COLLISION VECT
; .WORD DMACNZ,5 ;WRITE NON-ZERO CONSTANT, OBJECT ID
; .LONG 0 ;NO SCANNER BLIP
;
;NO_IMG:
; ; .WORD 4,4,0,0 ;WIDTH, HEIGHT, OFFSET,OFFSET
; .LONG IROM,0 ;SOURCE, PALETTE
;
;TIMER_COLOR EQU 0F5F5H ;CONSTANT USED FOR TIMER
;
;SETUP_TIMER:
; MOVI TIMER_UNITS,A14
; CALLR GET_DIGIT
; MOVE A0,A9 ;KEEP UNITS IN A9
;
; MOVI TIMER_TENS,A14
; CALLR GET_DIGIT
; MOVE A0,A10 ;THEY'RE SET!
; RETS
;
;GET_DIGIT:
; MMTM SP,A1
; CALLA GPALOBJ ;GET THE STUFF
; CALLA STFOBJ
;
; MOVI TIMER_COLOR,A1
; MOVE A1,*A0(OCONST),W
;
; CALLA INSOBJ ;ITS SET
; MMFM SP,A1
; RETS
;
;UPDATE_TIMER:
; MOVE A0,A3 ;FIRST DO TENS
; MOVE A3,A1
; SRL 4,A1
; JRNZ REAL_TENS
;
; MOVE A10,A0
; JRZ TENS_GONE
; CALLA DELPAL ;TRASH IT!
; CALLA DELOBJ
; CLR A10
;
; MOVI (TEN_X+ONE_X)/2,A0
; MOVE A0,*A9(OXVAL),L ;CENTER THE ONES
;
; JRUC TENS_GONE
;
;REAL_TENS:
; CMPI 1,A1 ;ARE WE DOWN TO "10"
; JRNZ NOT_ONE_0
;
; MOVI ONE_O_X,A0
; MOVE A0,*A10(OXVAL),L ;SLIDE IT OVER TO LOOK NICE!
;NOT_ONE_0:
; MOVE A10,A2 ;GET 10'S OBJECT IN A2
; CALLR UPDATE_NUMBER ;OBJECT A2 GETS NUMBER IN A1
;
;TENS_GONE:
; MOVE A3,A1
; MOVE A9,A2
; CALLR UPDATE_NUMBER
; RETS
; ;
;BLANK_TIMER:
; MMTM SP,A0
; CLR A0
; MOVE A0,*A9(OCONST),W
; MOVE A10,A10 ;TENS PRESENT?
; JREQ BT_NT ;NOPE
; MOVE A0,*A10(OCONST),W
;BT_NT:
; MMFM SP,A0
; RETS
;
**************************************************************************
* *
* UPDATE_NUMBER *
* *
* OBJECT IN A2 *
* NIBBLE IN A1 *
* *
* GET CORRECT NUMBER IMAGE IN THE OBJECT. *
* *
* *
**************************************************************************
;UPDATE_NUMBER:
; MMTM SP,A1,A4,A6,A7,A8
; MOVI RD15FONT,A6
; ANDI 0FH,A1
; ADDI LET_0-EX_PT,A1 ;INDEX TO TABLE
; SLL 5,A1 ;
; ADD A1,A6 ;POINT TO IMAGE (A1 FOR ANI)
; MOVE *A6,A1,L ;FETCH THE IMAGE FOR ANI
;
; MOVE A2,A8 ;OBJECT STRUCTURE FOR ANI
; MOVE *A2(OFLAGS),A4,W ;FETCH THE OFLAGS
; CALLA ANI ;SET NEW ANIMATION PICTURE
;
; MOVI TIMER_COLOR,A6 ;GET THE DRAWING COLOR BACK OUT.
; MOVE A6,*A2(OCONST),W
;
; MMFM SP,A1,A4,A6,A7,A8
; RETS
;
***************************************************************************
* *
* ISHSTD *
* *
* DID ANYONE MAKE THE HIGH SCORE TABLE. *
* A0=0 NO (EQ) *
* A0=1 PLAYER 1 MADE IT (NE) *
* A0=2 PLAYER 2 MADE IT (NE) *
* A0=3 NOBODY MADE IT (NE) *
* *
***************************************************************************
ISHSTD:
MMTM SP,A8,A10
MOVK 1,A0
MOVE @P1DATA+PSCORE,A8,L
MOVE @P2DATA+PSCORE,A10,L
CALLR CHECK_ALL_TIME
JRNZ ISHSTD1
CALLR CHECK_TODAY
JRNZ ISHSTD1
CLR A0
ISHSTD1
SWAP A8,A10
ADDK 2,A0
CALLR CHECK_ALL_TIME
JRNZ VERY_HIGH
CALLR CHECK_TODAY
JRNZ VERY_HIGH
SUBK 2,A0
VERY_HIGH:
MMFM SP,A8,A10
RETS
CHECK_ALL_TIME:
MMTM SP,A0,A2,A8
MOVE A8,A0
MOVE A10,A2 ;SHOW "OTHER" SCORE IN A2
MOVI ALL_TAB,A8
CALLR CHECK_SCORE
MMFM SP,A0,A2,A8
RETS
CHECK_TODAY:
MMTM SP,A0,A2,A8
MOVE A10,A2 ;SHOW "OTHER" SCORE IN A2
MOVE A8,A0
MOVI TOD_TAB,A8
CALLR CHECK_SCORE
MMFM SP,A0,A2,A8
RETS
.BSS INITTIMR,16
.BSS GET1FLG,16
.BSS GET2FLG,16
*
*TIMER FOR INITIAL PROCESS
*
INITTIM
CLR A0
MOVE A0,@GET1FLG,W
MOVE A0,@GET2FLG,W
CREATE BONPID,INTIML
MOVI 30,A1
MOVE A1,@INITTIMR,W
MOVE A1,*A0(PA10),L ;SET A10 TO 60
RETS
INTIML
MOVE @INITTIMR,A0,W
DEC A10
JRNE INTIML1
MOVI 60,A10
DEC A0
JRN INITTIMX
MOVE A0,@INITTIMR,W
INTIML1
CALLA BINBCD
MOVI >8300BD,A3
MOVE A12,-*SP,L
MOVK 2,A12
MOVK 1,A6
SLL 24,A0 ;SHIFT DIGITS INTO PLACE
CALLR HSNUML0
MOVE *SP+,A12,L
SLOOP 1,INTIML
INITTIMX
DIE ;WE FUCKING QUIT
*
*GET PLAYERS INITIALS - WAIT TILL DONE
*
GETINIT:
SLEEP 10
CALLR DONCK
JRNE GETINIT
GETINITX
SLEEP 60 ;WAIT A SEC. THEN BOOK
RETP
*
*CHECK IF INITIALS DONE
*
DONCK
MOVE @INITTIMR,A2,W
JREQ DONCKX
MOVE @GET1FLG,A0,W
MOVE @GET2FLG,A1,W
ADD A0,A1
DONCKX
RETS
*
*GET PLAYER 1 INITIALS
*
GETINIT1
MOVI P1ITAB,A0
MOVI LTRBX,A2 ;(OIMG)
JRUC GTINIT
P1ITAB
.LONG P1DATA+PSCORE ;SCORE VALUE
; .STRING "AAA",0
.LONG >00202020 ;STARTING INITIALS
.LONG >00000000 ;START BOX COORD
.IF YUNIT
.LONG SWITCH,SWITCH+4,SWITCH+18 ;SWITCH LOCATIONS
.ELSE
.LONG SWITCH,SWITCH+8,SWITCH+24
.ENDIF
.LONG >00420030 ;INITIAL DISPLAY ADDRESS
.LONG >26260000 ;COLOR:PALETTE
.LONG GET1FLG
*
*GET PLAYER 2 INITIALS
*
GETINIT2
MOVI P2ITAB,A0
MOVI LTRBX2,A2 ;(OIMG)
JRUC GTINIT
P2ITAB
.LONG P2DATA+PSCORE ;SCORE VALUE
; .STRING "AAA",0
.LONG >00202020 ;STARTING INITIALS
.LONG >00000005 ;START BOX COORD
.IF YUNIT
.LONG SWITCH+8,SWITCH+12,SWITCH+21 ;SWITCH LOCATIONS
.ELSE
.LONG SWITCH+4,SWITCH+12,SWITCH+25
.ENDIF
.LONG >00420120 ;INITIAL DISPLAY ADDRESS
.LONG >27270000 ;COLOR:PALETTE
.LONG GET2FLG
*
*GET YOUR INITIALS PROCESS
*A0=POINTER TO SETUP TABLE
*A2=OIMG
*A8=POINTER TO BOX OBJECT
*A9=DEBOUNCE TIMER, INITIAL ENTRY
*A10=DEBOUNCE TIMER, MOVE JOYSTICK
*A11=INITIAL #
*PDATA=SCORE
*PDATA+>20,PDATA+>28,PDATA+>30,PDATA+>38 = INITIAL STRING
*PDATA+>40=CURRENT BOX COORD
*PDATA+>60=MOVE STICK ADDRESS
*PDATA+>80=FIRE STICK ADDRESS
*PDATA+>A0=START BUTTON ADDRESS
*PDATA+>C0=INITIAL DISPLAY BASE ADDRESS
*PDATA+>E0=COLOR:PALETTE INITIAL
*PDATA+>100=INITIAL D0NE FLAG (DONE=0)
*
GTINIT
MOVE A13,A8
ADDI PDATA,A8
MOVE *A0+,A1,L
MOVE *A1+,*A8+,L ;PUT THE SCORE
MOVK 8,A1
GTI0L
MOVE *A0+,A3,L
MOVE A3,*A8+,L
DSJS A1,GTI0L
MOVK 1,A1
MOVE A1,*A3,W ;INCREMENT DONE FLAG
CLR A11 ;CURRENT INITIAL WORKING ON
CLR A10 ;JOYSTICK DEBOUNCE TIMER
CLR A9 ;FIRE/START DEBOUNCE
*CREATE BOX OBJECT
CLR A0 ;A0=OXVAL
CLR A1 ;A1=OYVAL
MOVI 9EH,A3 ;(OZPOS)
MOVI DMAWNZ,A4 ;(OFLAGS) NON-ZERO VALUE
MOVI 0,A5 ;(OID)
CLR A6 ;(OXVEL)
CLR A7 ;(OYVEL)
CALLA BEGINOBJ
*GET MOVE SWITCHES
GTL
CMPI 3,A11
JRHS GTL4 ;ENTERED 'EM ALL
CALLR DONCK
JRNE GTL0
MOVI 3,A11 ;TIMES UP STUFF EM IN
JRUC GTL3X
GTL0
MOVE *A13(PDATA+>60),A0,L ;GET MOVE SWITCH ADDRESS
MOVE *A0,A1,W
NOT A1
SLL 28,A1
SRL 28,A1
JRNE GTL1
CLR A10 ;CLEAR DEBOUNCE TIMER
JRUC GTL5
GTL1
MOVE A10,A10
JRNE GTL5
MOVK 12,A10
SLL 4,A1
ADDI IJOYTAB,A1
MOVB *A1,A0 ;GET DX
MOVB *A1(8),A1 ;GET DY
MOVE *A13(PDATA+>40),A2 ;GET X COORD
MOVE *A13(PDATA+>50),A3 ;GET Y COORD
ADD A2,A0 ;ADD DX, CHECK LIMITS
JRNN GM1
CLR A0
GM1
CMPI 5,A0
JRLS GM2
MOVK 5,A0
GM2
ADD A3,A1 ;ADD DY CHECK LIMITS
JRNN GM3
CLR A1
GM3
CMPI 4,A1
JRLS GM4
MOVK 4,A1
GM4
MOVE A0,*A13(PDATA+>40),W ;SAVE COORDS
MOVE A1,*A13(PDATA+>50),W
*FORM BOX XY COORD AND UPDATE IT
GTL5
MOVE *A13(PDATA+>40),A0,W ;GET COORDS
MOVE *A13(PDATA+>50),A1,W
MOVI >15,A3
MOVI >16,A5
MPYU A0,A3 ;FORM X OFFSET
MPYU A1,A5 ;FORM Y OFFSET
ADDI >82,A3
ADDI >0E,A5
MOVE A3,*A8(OXPOS),W ;UPDATE POSITION
MOVE A5,*A8(OYPOS),W
*UPDATE YOUR LETTER VALUE
*A0=X OFFSET
*A1=Y OFFSET
MOVK 6,A3
MPYU A1,A3
ADD A0,A3 ;THIS IS THE INDEX TO MATIRX
SLL 3,A3
ADDI INITMAT,A3
MOVB *A3,A0
MOVE A11,A4
SLL 3,A4
ADD A13,A4
ADDI PDATA+>20,A4
MOVB A0,*A4 ;STORE OUT CURRENT INITIAL
*UPDATE LETTER POSITION SELECTED
MOVE *A13(PDATA+>80),A0,L ;FIRE STICK COORD
MOVE *A0,A0,W ;READ IT FOLKS
NOT A0
SLL 28,A0
SRL 27,A0
MOVE *A13(PDATA+>A0),A1,L
MOVE *A1,A1,W
NOT A1
SLL 31,A1
SRL 31,A1
ADD A1,A0
JRNE GTL3
CLR A9 ;CLEAR DEBOUNCE TIMER
JRUC GTL4
GTL3
MOVE A9,A9 ;DEBOUNCE STILL ON
JRNE GTL4
MOVI 120,A9
MOVB *A4,A0 ;CHECK FOR RUB DUDES...
CMPI >3C,A0
JRNE GTL3A ;NO....
DEC A11
JRNN GTL30
CLR A11 ;CAN'T RUB FIRST CHAR
JRUC GTL4
GTL30
PUSH A0
MOVI GOGO,A0
CALLA ONESND
PULL A0
MOVK >20,A0
MOVB A0,*A4 ;THROW OUT A SPACE
JRUC GTL4
GTL3A
PUSH A0
MOVI GOGO,A0
CALLA ONESND
PULL A0
INC A11
CMPI 3,A11
JRLO GTL4
GTL3X
MOVE A8,A0
CALLA DELOBJ
MOVE *A13(PDATA+>100),A0,L
CLR A1
MOVE A1,*A0,W ;CLEAR DONE FLAG
CALLR GTX ;UPDATE TABLE ENTRY
*UPDATE YOUR LETTER DISPLAY
GTL4
MOVE A13,A2 ;GET INITIAL STORE ADDRESS
ADDI PDATA+>20,A2
MOVK 3,A1 ;DO THREE INITIALS
MOVE *A13(PDATA+>C0),A3,L ;GET BASE SCREEN ADDRESS
GTL5L
MOVB *A2,A0
MMTM SP,A1,A2,A3
MOVE *A13(PDATA+>E0),A1,L ;GET COLOR:PALETTE
CALLR INITOUT
MMFM SP,A1,A2,A3
ADDI >19,A3 ;INC SCREEN COORD
ADDK 8,A2 ;INC DISPLAY ADDRESS
DSJS A1,GTL5L
*DEC DEBOUNCE TIMERS
MOVE A10,A10 ;DEC TIMER ?
JREQ GTL6 ;NO, ALREADY ZERO
DEC A10 ;DEC IT
GTL6
MOVE A9,A9 ;DEC TIMER ?
JREQ GTL7 ;NO, ALREADY ZERO
DEC A9 ;DEC IT
GTL7
SLEEP 1
JRUC GTL
; CALLR DONCK
; JRNE GTL
*STUFF HI SCORE
GTX
MOVE *A13(PDATA),A0,L ;GET SCORE POINTS
MOVE A13,A1
ADDI PDATA+>20,A1 ;POINT TO INITIAL STORAGE
MOVI TOD_TAB,A8 ;ALWAYS ADD TO TODAYS (EVEN IF SPACES)
CALLR ADD_ENTRY ;ADD EM TO THIS ONE IF NEC.
MOVI ALL_TAB,A8
CALLR ADD_ENTRY ;ADD EM TO THE TABLE
JRC TOO_BAD ;DIDN'T MAKE ALL TIME
CALLR DELAY_HSRESET ;NEW ENTRY....DON'T RESET TOO QUICK
TOO_BAD:
RETS
*
*INITIAL ENTRY JOYSTICK TABLE
* ;RLDU
*
IJOYTAB
.BYTE 0,0 ;0000
.BYTE 0,-1 ;0001
.BYTE 0,1 ;0010
.BYTE 0,0 ;0011
.BYTE -1,0 ;0100
.BYTE -1,-1 ;0101
.BYTE -1,1 ;0110
.BYTE -1,0 ;0111
.BYTE 1,0 ;1000
.BYTE 1,-1 ;1001
.BYTE 1,1 ;1010
.BYTE 1,0 ;1011
.BYTE 0,0 ;1100
.BYTE 0,-1 ;1101
.BYTE 0,1 ;1110
.BYTE 0,0 ;1111
*
*INITIAL MATRIX
*
INITMAT:
.STRING "ABCDEFGHIJKLMNOPQRSTUVWXYZ!%?<"
*
**************************************************************************
* *
* A2_CHECK *
* *
* DOES THE SCORE IN A2 MATCH EITHER OF THE PLAYER'S SCORE. *
* .EQ. MEANS YES *
* .NE. MEANS NO *
* *
* THIS IS A NARCSPRY MODULE MOVED HERE TO FREE *
* NARCSPRY DEPENDANCY ON NARCEQU (T.I. B.D. OVERFLOWS) *
* *
**************************************************************************
A2_CHECK:
MMTM SP,A0
MOVE @P1DATA+PSCORE,A0,L
CMP A2,A0
JREQ A2_SUCC ;IT WAS PLAYER 1'S SCORE
MOVE @P2DATA+PSCORE,A0,L
CMP A2,A0
A2_SUCC:
MMFM SP,A0
RETS
**************************************************************************
* *
* CHECK_INITS *
* *
* A1 POINTS AT A SET OF INITIALS ENTERED. RETURN .EQ. *
* IF THEY'RE ALL SPACES (OR ZERO). *
* *
**************************************************************************
CHECK_INITS:
MMTM SP,A0,A1,A2
MOVI NUM_INITS,A2
CHECK_NEXT:
MOVB *A1,A0 ;GET AN INITIAL
JRZ SPACE_FOUND ;NULL IS A SPACE
CMPI SPACE,A0 ;IS IT A REAL SPACE?
JRNZ LET_FOUND
SPACE_FOUND:
ADDI BYTE_SIZE,A1
DSJS A2,CHECK_NEXT
CLR A2 ;SET Z BIT ON FALL THROUGH
LET_FOUND:
MMFM SP,A0,A1,A2
RETS
**************************************************************************
* *
* CHECK_SCORE *
* *
* THIS IS CALLED WITH A SCORE IN A0 TO SEE IF IT *
* IS HIGH ENOUGH TO MAKE THE TABLE. *
* *
* THE OTHER PLAYER'S SCORE IS PASSED IN A2. IF *
* THE PLAYER MAKES THE LAST POSITION OF THE TABLE, *
* THEN HIS SCORE IS COMPARED AGAINST THE OTHER SCORE *
* IT MUST BE HIGHER THAN THE OTHER SCORE, OTHERWISE *
* HE WILL ENTER HIS INITIALS, BUT THERE WILL BE NO *
* PLACE TO PUT THEM WHEN HIS BUDDY IS DONE ENTERING HIS! *
* *
* THIS ROUTINE CALLS FIND_TABLE_LEVEL WHICH RETURNS *
* THE POINT IN THE TABLE THAT THE PASSED SCORE WOULD *
* LAND. THIS VALUE MUST BE LESS THAN OR EQUAL TO *
* THE "TB_VISIBLE" VALUE FOR THE TABLE. THIS WOULD *
* MEAN THAT WE WANT TO GET THE PLAYER'S INITIALS. *
* *
* A8 CONTAINS ROM POINTER FOR TABLE TO CHECK. *
* RETURN A0 = 0 (AND .EQ.) IF SCORE ISN'T HIGH ENOUGH *
* AND A0 = POSITION IN TABLE IF SCORE MAKES IT. *
* *
**************************************************************************
CHECK_SCORE:
MMTM SP,A1,A3,A9,A10
MOVE A0,A3 ;STASH SCORE IN A3
CALLR FIND_TABLE_LEVEL ;SEE WHERE WE LAND IN THIS TABLE
JRZ ANSWER_IN_A0 ;ZERO.....GUY DIDN'T MAKE IT
MOVE *A8(TB_VISIBLE),A1,W ;GET THE NUMBER "ENTERED"
CMP A1,A0 ;A0 MUST BE LESS OR EQUAL
JRLO ANSWER_IN_A0 ;NOT LAST ENTRY...RETURN SUCCESS
JRHI DIDNT_MAKE_HSTD
*
* GUY IS GOING FOR LAST POSITION.....SEE IF HIS BUDDY IS
* GOING TO NOSE HIM OUT:
*
CMP A2,A3 ;HI MUST BE HIGHER THAN BUDDY
JRHI ANSWER_IN_A0
*
*
* ****** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ******
* ****** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ******
*
* NOTE THAT IF BOTH PLAYERS HAVE AN IDENTICAL SCORE THAT
* WOULD MAKE THE LAST POSITION OF A TABLE, THEN THEY
* WONT GET TO ENTER THEIR INITIALS!!!!!!
*
* TOUGH LUCK! -LED 10/22/88
*
* ****** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ******
* ****** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ******
*
*
* WE WOULD MAKE THE PHYSICAL TABLE, BUT WE'RE OUT OF
* WHAT THE PLAYER CAN SEE....RETURN FALSE
*
DIDNT_MAKE_HSTD:
CLR A0 ;RETURN FAILURE
ANSWER_IN_A0:
MOVE A0,A0 ;SET EQ BIT ACCORDINGLY
MMFM SP,A1,A3,A9,A10
RETS
**************************************************************************
* *
* ADD_ENTRY *
* *
* THIS IS CALLED AFTER "ENTER YOUR INITIALS" TO *
* ADD AN ENTRY TO THE TABLE. A0 CONTAINS THE *
* SCORE OF THE PLAYER. A1 CONTAINS A POINTER *
* TO THE FETCHED INITIALS. THE INITIALS ARE *
* STORED AS CONSECUTIVE BYTES IN CONVENTIONAL *
* (1 BYTE TAKES 1 BYTE SPACE) RAM. *
* *
* A8 contains a the table to store the entry in. *
* *
* RETURN CARRY SET IF IT DIDN'T MAKE IT INTO REQUESTED TABLE *
* *
**************************************************************************
ADD_ENTRY:
MMTM SP,A0,A1,A2,A3,A4,A7,A9,A10
CALLR ROM_PTRS ;SETUP FOR THIS TABLE
MOVE A0,A4 ;STASH THE SCORE A SEC.
CLR A2 ;DONT WORRY ABOUT OTHER GUY AT THIS POINT
CALLR CHECK_SCORE ;DOES THE REQUEST MAKE IT?
SETC ;ANTICIPATE FAILURE
JRZ DIDNT_MAKE_IT ;DON'T KNOW WHY I GOT THESE INITS.
*
* A0 NOW HAS THE PLACE FOR THE NEW GUY.
* MOVE THE ENTIRE TABLE DOWN 1 UNIT.
*
MOVE A10,A3 ;LAST GUY IN TABLE IS DESTINATION
COPY_DOWN_LOOP:
MOVE A3,A2 ;GUY BEFORE HIM IS SOURCE
DEC A2 ;A2 NOW HAS SOURCE
CMP A0,A2 ;IS SOURCE LOWER THAN OUR SLOT?
JRLO COPY_DONE ;IT IS...DON'T MOVE HIM.
CALLR COPY_ENTRY ;COPY A2 ENTRY TO A3
DEC A3 ;MOVE DOWN TO ONE BEFORE
JRUC COPY_DOWN_LOOP
COPY_DONE:
CALLR PUT_SCORE_FOR_ENTRY ;SCORE IN A4 WRITTEN TO ENTRY A0
*
* INITAIAL POINTER IS IN A1
* TABLE OFFSET IN A0
*
CALLR PT_ENTRY ;GET ENTRY POINTER IN A7
ADDI HS_INITS,A7 ;POINT AT FIRST INITIAL
MOVI NUM_INITS,A2 ;THIS IS NUMBER OF INITIALS
MMTM SP,A0 ;SAVE A0
INIT_COPY_LOOP:
MOVB *A1,A0 ;GET AN INITIAL
JRNZ NOT_BLANK
MOVI SPACE,A0 ;REPLACE BLANKS WITH SPACES
NOT_BLANK:
CALLR WC_BYTEI ;WRITE THE BYTE AND INCREMENT
ADDI BYTE_SIZE,A1 ;A1 TO NEXT BYTE PLEASE
DSJ A2,INIT_COPY_LOOP
MMFM SP,A0 ;GET BACK ENTRY NUMBER
CALLR FORM_HS_CKSUM_AND_STORE ;FOR CHECKSUM FOR THIS ENTRY AND STORE!
CLRC ;RETURN SUCCESS!
DIDNT_MAKE_IT:
MMFM SP,A0,A1,A2,A3,A4,A7,A9,A10
RETS
**************************************************************************
* *
* FIND_TABLE_LEVEL *
* *
* THIS IS CALLED TO COMPARE THE SCORE IN A0 TO *
* THE TABLE POINTED TO BY A8. *
* *
* RETURN PHYSICALLY WHERE IT FITS IN A0, AND *
* SET THE Z FLAG ACCORDINGLY *
* *
**************************************************************************
FIND_TABLE_LEVEL:
MMTM SP,A1,A2,A3
CALLR ROM_PTRS ;SETUP FOR THIS TABLE
CALLR VAL_TAB ;FIX THE TABLE IN CASE ITS BROKEN.
JRC FTL_FAIL ;CAN'T VALIDATE..SAY SCORE DIDN'T MAKE IT
MOVE A0,A2 ;KEEP SCORE IN A2
MOVK 1,A0 ;START AT 1 AND WORK UP.
CHECK_NEXT_SCORE:
CALLR GET_HSCR ;FETCH A0 ENTRY'S SCORE IN A1
CMP A1,A2 ;HOW DO WE FARE AGAINST A1?
JRHI FOUND_THE_SPOT ;WE FOUND THE SPOT
INC A0 ;KEEP MOVING DOWN TILL WE FIT
CMP A10,A0 ;ARE WE LOOKING AT THE LAST ONE?
JRLS CHECK_NEXT_SCORE
FTL_FAIL:
CLR A0 ;WE'RE NOT HIGH ENOUGH RETURN FAILURE
FOUND_THE_SPOT:
MOVE A0,A0 ;MAKE SURE YOU SET THE FLAGS
MMFM SP,A1,A2,A3
RETS
**************************************************************************
* *
* GET_HSCR *
* *
* THIS IS CALLED TO FETCH THE SCORE FROM CMOS FOR *
* A GIVEN ENTRY. *
* *
* ENTRY NUMBER PASSED IN A0. *
* SCORE RETURNED IN A1. *
* *
**************************************************************************
GET_HSCR:
MMTM SP,A7,A0
CALLR PT_ENTRY ;POINT A7 AT ENTRY
ADDI HS_SCORE,A7 ;INDEX SCORE PART.
CALLR RC_LONG ;FETCH THE LONG WORD INTO A0
MOVE A0,A1 ;MOVE TO A1
MMFM SP,A7,A0
RETS
**************************************************************************
* *
* PUT_SCORE_FOR_ENTRY *
* *
* THIS IS CALLED TO WRITE OUT THE SCORE FOR A GIVEN ENTRY. *
* ENTRY SPECIFIED BY A0. *
* SCORE PASSED IN A4. *
* *
**************************************************************************
PUT_SCORE_FOR_ENTRY:
MMTM SP,A7,A0
CALLR PT_ENTRY ;POINT A7 AT ENTRY
ADDI HS_SCORE,A7 ;INDEX SCORE PART.
MOVE A4,A0 ;MOVE SCORE TO A0
CALLR WC_LONG ;WRITE OUT THE LONG WORD
MMFM SP,A7,A0
RETS
**************************************************************************
* *
* LOW LEVEL HSTD PROCESSING *
* *
**************************************************************************
*
* FOR HIGH SCORE ROUTINES
*
* A8 = ROM POINTER FOR A GIVEN TABLE STATS
* A9 = RAM POINTER FOR CMOS DATA
* A10 = NUMBER OF ENTRIES IN THE TABLE
*
* A0 = PARTICULAR ENTRY TO DEAL WITH
* 0 = FILL ENTRY (POINTER ROUTINES POINT HERE IF ERROR)
* 1 = HIGHEST SCORE IN TABLE
* N = NTH SCORE
*
* A1 = OUTPUT OF CHECKSUM ROUTINE (BYTE)
*
* A7 = POINTER TO CURRENT ENTRY
*
* A4,A5,A6 SCRATCH
*
**************************************************************************
* *
* FORM_HS_CKSUM *
* *
* THIS IS CALLED TO FORM THE CHECKSUM FOR THE SCORE *
* NUMBER IN A0. (RAM POINTER ASSUMED IN A9). *
* CHECKSUM IS RETURNED IN A1. THIS IS A *BYTE*. *
* *
* CHECKSUM IS COMPUTED AS THE COMPLEMENT OF THE SIMPLE SUM *
* OF THE BYTES IN THE ENTRY. *
* *
* THIS ROUTINE RETURNS WITH THE Z BIT SET (.EQ.) IF THE *
* CHECKSUM FOR THIS ENTRY MATCHES. *
* *
**************************************************************************
FORM_HS_CKSUM:
MMTM SP,A0,A4,A6,A7
CALLR PT_ENTRY ;A7 = POINTER TO CURRENT ENTRY
MMTM SP,A7 ;SAVE POINTER TO ENTRY
MOVI HS_BYTES_TO_CHECK,A4 ;COUNT DOWN THE BYTES
CLR A1 ;KEEP SUM IN A1
ADD_A_BYTE:
CALLR RC_BYTEI ;GET A BYTE INTO A0
ADD A0,A1 ;ADD TO SUM
DSJ A4,ADD_A_BYTE ;ONE MORE ADDED
NOT A1 ;CHECKSUM IS NOW IN LOW BYTE
ANDI BYTE_MASK,A1 ;MASK SO ITS COOL
MMFM SP,A7 ;GET POINTER BACK
ADDI HS_CKBYTE,A7 ;POINT AT CHECKBYTE
CALLR RC_BYTE ;READ IN THE BYTE
CMP A0,A1 ;COMPARE WHAT'S THERE TO WHAT WE GOT
MMFM SP,A0,A4,A6,A7 ;Z BIT RETURNS COMPARE
RETS ;A1 RETURNS CKSUM
**************************************************************************
* *
* FORM_HS_CKSUM_AND_STORE *
* *
* THIS IS USED TO SET THE CHECKSUM FOR THE CURRENT *
* ENTRY (A0) TO THE CORRECT VALUE. *
* *
**************************************************************************
FORM_HS_CKSUM_AND_STORE:
MMTM SP,A0,A7
CALLR FORM_HS_CKSUM ;GET THE CKSUM IN A1, POINTER IN A7
CALLR PT_ENTRY ;POINT AT THE VALUE
ADDI HS_CKBYTE,A7 ;POINT AT CHECKBYTE
MOVE A1,A0 ;GET CHECKBYTE TO A0
CALLR WC_BYTE ;WRITE OUT THE BYTE
MMFM SP,A0,A7
RETS
**************************************************************************
* *
* PT_ENTRY *
* *
* THIS IS CALLED TO POINT AT A GIVEN ENTRY OF *
* THE HIGH SCORE TABLE. THIS ROUTINE BASES *
* ACTIVITY ON ROM POINTER IN A8. IT FETCHES *
* FRESH COPIES OF THE A9 RAM POINTER AND THE *
* A10 ENTRY COUNTER. IT RETURNS THE ENTRY *
* POINTER IN A7. *
* *
* A0 SPECIFIES WHICH ENTRY TO POINT AT *
* A8,A9,A10 AND SYSCTRL ASSUMED SET PROPERLY *
* A7 RETURNED POINTING TO THAT ENTRY *
* *
**************************************************************************
PT_ENTRY:
CMP A10,A0 ;A10 IS MAX VALUE
JRLS POINTER_IN_RANGE
.IF DEBUG
JRUC $ ;HANG IN DEVELOPMENT
.ENDIF
MOVE A9,A7 ;RETURN ZERO OFFSET IN FIELD
RETS
POINTER_IN_RANGE:
MOVI HS_SIZE,A7 ;SIZE OF ENTRY
MPYU A0,A7 ;OFFSET OF ENTRY
ADD A9,A7 ;ADD IN THE BASE
RETS
**************************************************************************
* *
* ROM_PTRS *
* *
* THIS IS CALLED TO LOAD UP THE ROM STRUCTURE *
* DATA INTO REGISTERS. *
* *
* THIS ALSO SETS UP STATUS WORD TO SELECT THE CMOS *
* BANK SELECT FOR WHERE THE PARTICULAR TABLE RESIDES. *
* *
* INPUT A8 = HSTD STRUCTURE ROM POINTER. *
* *
* OUTPUT A9 = CMOS RAM POINTER TO BASE OF TABLE *
* OUTPUT A10 = LAST ENTRY IN TABLE. TABLE WILL *
* HAVE A10+1 ENTRIES SINCE ENTRY *
* 0 IS A FILLER. *
* *
**************************************************************************
ROM_PTRS:
MMTM SP,A0,A1 ;SCRATCH REGGIES
MOVE *A8(TB_POINTER),A9,L ;GET CMOS POINTER
MOVE *A8(TB_COUNT),A10,W ;GET NUMBER OF ENTRIES
MOVE *A8(TB_PAGE_BITS),A1 ;GET OUR CMOS PAGE BITS
CALLR SET_PAGE ;
MMFM SP,A0,A1 ;SCRATCH REGGIES
RETS
**************************************************************************
* *
* SET_PAGE *
* *
* This is called to set the CMOS page to the bits *
* contained in A1. *
* *
**************************************************************************
SET_PAGE:
MMTM SP,A0,A1
ANDI CMOS_PAGE_SELECT_BITS,A1 ;KILL SIGN EXTEND..SAVE BITS
PUSHST ;SAVE INTERRUPT STATUS
DINT ;STOP INTERRUPTS
MOVE @SYSCOPY,A0,W ;GET THE RAM COPY
ANDNI CMOS_PAGE_SELECT_BITS,A0 ;REMOVE THE CURRENT PAGE SELECT
OR A1,A0 ;ADD IN OUR BITS
MOVE A0,@SYSCOPY,W ;PUT THEM BACK IN THE RAM COPY
MOVE A0,@SYSCTRL,W ;NOW THE HARDWARE
POPST ;OK TO RE-START INTS
MMFM SP,A0,A1
RETS
**************************************************************************
* *
* INIT_TAB *
* *
* This entrypoint is called at power up to *
* clear out "today's" high score table. We do *
* this job, and then we do the job on the *
* all time table for high score reset if *
* necessary. *
* *
**************************************************************************
INIT_TAB:
MMTM SP,A8,A0
MOVI TOD_TAB,A8
CALLR INIT_TB ;RESET TODAYS TABLE
CALLR GET_HSC ;CHECK THE HIGH SCORE RESET COUNTER
JRNZ INIT_TAB1 ;NOT ZERO...NO MORE ACTIVITY
*
* ITS ZERO....SEE IF ITS TURNED OFF
*
MOVI ADJHSRES,A0
CALLA GET_ADJ ;GET THE ADJUSTED VALUE
JRZ INIT_TAB1 ;ITS TURNED OFF...NO ACTION.
MOVI ALL_TAB,A8 ;RESET THE ALL TIME TABLE
CALLR INIT_TB ;INIT THE ALL TIME TABLE
CALLR INIT_HSR ;RESET THE COUNTER TO ADJUSTED VALUE
INIT_TAB1:
MMFM SP,A8,A0
RETS
**************************************************************************
* *
* INIT_TB *
* *
* THIS IS CALLED TO SETUP A HIGH SCORE TABLE WITH *
* FACTORY ENTRIES. *
* *
* A8 = ROM TABLE POINTER *
* *
**************************************************************************
INIT_TB:
MMTM SP,A5,A6,A7,A0
CALLR ROM_PTRS ;STUFF TABLE DATA
MOVE *A8(TB_FACTORY),A6,L ;GET THE FACTORY TABLE
MOVE A10,A5 ;NUMBER OF VALID ENTRIES
INC A5 ;1 MORE TO HOLD ZERO ENTRY
MOVI HS_SIZE_IN_BYTES,A1 ;SIZE OF 1 ENTRY
MPYU A1,A5 ;A7 HAS NUMBER OF WORDS TO MOVE
MOVE A9,A7 ;CMOS POINTER IN A7
INIT_TB_1:
MOVB *A6,A0 ;GET A BYTE FROM ROM
ADDI BYTE_SIZE,A6 ;KICK ROM POINTER
CALLR WC_BYTEI ;WRITE THE BYTE AND INCREMENT
DSJS A5,INIT_TB_1 ;UNTIL THEY'RE ALL THERE.
MOVE A10,A0 ;POINT AT LAST ENTRY
INIT_TB_2:
CALLR FORM_HS_CKSUM_AND_STORE ;SET ITS CHECKSUM
DEC A0 ;MOVE DOWN
JRNN INIT_TB_2 ;SET EACH ONE INCLUDING ZERO
MMFM SP,A5,A6,A7,A0
RETS
**************************************************************************
* *
* COPY_ENTRY *
* *
* THIS IS CALLED TO COPY 1 ENTRY OF THE TABLE TO A *
* DIFFERENT LOCATION IN THE TABLE. *
* *
* A8,A9,A10,SYSCTRL ASSUMED TO BE SETUP ALREADY *
* A2 = SOURCE ENTRY (NUMBER) *
* A3 = DESTINATION ENTRY (NUMBER) *
* *
**************************************************************************
COPY_ENTRY:
MMTM SP,A0,A4,A5,A6,A7
MOVI HS_SIZE_IN_BYTES,A4 ;ENTRY SIZE IN BYTES
MOVE A2,A0 ;FIRST POINT FOR A0
CALLR PT_ENTRY
MOVE A7,A6 ;A6 = SOURCE POINTER
MOVE A3,A0
CALLR PT_ENTRY ;A5 = DESTINATION
MOVE A7,A5
COPY_LOOP:
*
* IN THIS LOOP WE MOVE A BYTE AT A TIME.
* SINCE THE WORD AND LONG DO THE SHIFTING AND
* MASKING AND CALL MULTIPLE ROUTINES, THIS IS
* THE MOST EFFICIENT MODE OF OPERATION.
*
MOVE A6,A7 ;SOURCE IN CMOS REGGIE
CALLR RC_BYTEI ;FETCH A WORD
MOVE A7,A6
MOVE A5,A7 ;DESTINATION
CALLR WC_BYTEI ;WRITE IT
MOVE A7,A5 ;BACK TO DEST REGGIE
DSJ A4,COPY_LOOP ;UNTIL ALL WORDS ARE COPIED
MMFM SP,A0,A4,A5,A6,A7
RETS
**************************************************************************
* *
* VAL_TAB *
* *
* THIS ROUTINE IS CALLED WHEN WE ARE INTERESTED IN *
* THE HSTD TABLE DATA. A8 CONTAINS THE ROM POINTER *
* FOR THE TABLE. FOR ANY ENTRIES THAT WE THROW *
* OUT, WE MOVE THE REST OF THE TABLE UP, AND CREATE *
* A NEW ENTRY AT THE END OF THE TABLE. *
* *
* A2 = 0 ON OUTSIDE CALL. *
* A2 = 1 ON RECURSIVE CALL (THE CHECK AFTER RE-INIT) *
* *
* THERE ARE 3 CHECKS MADE FOR EACH ENTRY: *
* *
* 1) IS CHECKSUM CORRECT. *
* 2) IS SCORE ALL NUMERIC *
* 3) ARE INITIALS ALL VALID ENTRIES. *
* *
* OUTPUT CC = TABLE OK *
* CS = PROBLEM THAT CAN'T BE RECTIFIED *
* (PROBABLY BAD RAM) *
* *
* A2 = 0 ...table ok, or cleaned up *
* A2 otherwise meanes table initialized *
* *
**************************************************************************
VAL_TAB:
CLR A2 ;indicate first call in
CALLR DO_VALIDATE ;validate
RETS
DO_VALIDATE:
MMTM SP,A0,A1,A3,A4,A5,A6,A7
CALLR ROM_PTRS ;SETUP FOR TABLE
MOVI 1,A0 ;ITERATE THROUGH THE ENTRIES
CLR A1 ;COUNT ERRORS
CHECK_A0_ENTRY:
CALLR CHECK_ENTRY ;IS THE ENTRY OK?
JRNC VT_1 ;YEP.
CALLR REMOVE_ENTRY ;REMOVE THIS ENTRY
INC A1
MOVE *A8(TB_ERROR_COUNT),A3 ;GET THRESHOLD
CMP A3,A1 ;ARE WE THERE?
JRLO CHECK_A0_ENTRY ;NOPE...CHECK MOVE UP ENTRY AT A0
*
* TABLE IS MESSED UP....RE-INITIALIZE IT PLEASE
*
MOVE A2,A2 ;IS THIS RECURSIVE CHECK AFTER INIT?
JRNZ CANT_VALIDATE ;THEN RETURN FAILURE
CALLR INIT_TB ;INIT THIS TABLE PLEASE
MOVK 1,A2 ;INDICATE RECURSIVE CALL
CALLR DO_VALIDATE ;IS IT ALRIGHT NOW?
MMFM SP,A0,A1,A3,A4,A5,A6,A7
RETS
*
* LAST ENTRY WAS VALID...MOVE TO NEXT
*
VT_1:
INC A0 ;KICK IT
CMP A10,A0 ;STILL IN TABLE?
JRLS CHECK_A0_ENTRY ;YEP....CHECK THIS ENTRY
CLRC ;RETURN VALID!
MMFM SP,A0,A1,A3,A4,A5,A6,A7
RETS
CANT_VALIDATE:
SETC ;RETURN FAILURE!
MMFM SP,A0,A1,A3,A4,A5,A6,A7
RETS
**************************************************************************
* *
* CHECK_ENTRY *
* *
* THIS IS CALLED TO CHECK THE ENTRY INDICATED BY *
* A0. *
* *
* CC = OK *
* CS = ENTRY BAD *
* *
**************************************************************************
CHECK_ENTRY:
MMTM SP,A0,A1,A2,A3,A7
CALLR FORM_HS_CKSUM ;CHECK OUT CKSUM FIRST
JRNZ CHECK_FAIL ;BAD CHECKSUM....ITS BAD
*
* CHECKSUM OK...CHECK SCORE
*
CALLR GET_HSCR ;SCORE IN A1
MOVE A1,A3 ;SAVE COPY OF SCORE
CHECK_DIGIT:
MOVE A1,A2 ;COPY FOR NEXT NIBBLE
ANDI 0FH,A2 ;MASK THE NIBBLE
CMPI 9,A2
JRHI CHECK_FAIL ;NIBBLE TOO HIGH
SRL 4,A1 ;SHIFT DOWN TO NEXT NIBBLE
JRNZ CHECK_DIGIT
DEC A0 ;MAKE SURE WE ARE LOWER THAN PREVIOUS SCORE!
JREQ FIRST_ENT ;WE'RE THE 1ST IN THE TABLE
CALLR GET_HSCR ;GET THE SCORE FOR THE GUY BEFORE US
CMP A1,A3 ;OURS MUST BE LOWER OR SAME
JRHI CHECK_FAIL ;OURS IS BIGGER....REMOVE US
FIRST_ENT:
INC A0 ;RESTORE THE ENTRY NUMBER
*
* SCORE OK...CHECK INITIALS
*
CALLR PT_ENTRY ;POINT A7 AT ENTRY
ADDI HS_INITS,A7 ;POINT AT FIRST INITIAL
MOVI NUM_INITS,A2 ;THIS IS NUMBER OF INITIALS
NEXT_LETTER:
CALLR RC_BYTEI ;FETCH A BYTE
CALLR VERIFY_LETTER ;SEE IF ITS VALID.
JRC CHECK_FAIL ;NOT A LETTER...BYTE
DSJ A2,NEXT_LETTER
CLRC ;RETURN PASS
MMFM SP,A0,A1,A2,A3,A7
RETS
CHECK_FAIL:
SETC
MMFM SP,A0,A1,A2,A3,A7
RETS
**************************************************************************
* *
* VERIFY_LETTER *
* *
* THIS IS CALLED FOR EACH INITIAL LETTER TO SEE *
* IF ITS VALID. *
* *
* CC = VALID *
* CS = NOT VALID *
* *
**************************************************************************
VERIFY_LETTER:
ANDI BYTE_MASK,A0 ;KEEP JUST THE BYTE
CMPI '!',A0 ;SPACE?
JREQ VERIFY_PASS ;ITS OK.
CMPI '%',A0 ;SPACE?
JREQ VERIFY_PASS ;ITS OK.
CMPI '?',A0 ;SPACE?
JREQ VERIFY_PASS ;ITS OK.
CMPI SPACE,A0 ;SPACE?
JREQ VERIFY_PASS ;ITS OK.
CMPI LET_A,A0 ;BETWEEN A-Z?
JRLO VERIFY_FAIL
CMPI LET_Z,A0
JRHI VERIFY_FAIL
VERIFY_PASS:
CLRC
RETS
VERIFY_FAIL:
SETC
RETS
**************************************************************************
* *
* REMOVE_ENTRY *
* *
* THIS IS CALLED TO REMOVE A BAD ENTRY FROM THE TABLE. *
* IT DELETES THE ENTRY INDICATED BY A0. *
* *
* IT BUBBLES THE REST OF THE TABLE UP 1 UNIT. *
* *
* IT THEN PUTS THE LOWEST SCORE FROM THE ROM TABLE *
* WITH INITIALS IN THAT ENTRY. *
* *
**************************************************************************
REMOVE_ENTRY:
MMTM SP,A0,A1,A2,A6,A7
MOVE A0,A3 ;THIS IS DEST
MOVE A3,A2 ;SOURCE IS 1 BELOW
BUBBLE_ANOTHER:
INC A2 ;NOW WE'RE SET FOR A COPY...
CMP A10,A2 ;IS SOURCE OUT OF RANGE?
JRHI BUBBLE_DONE ;YEP....WE'RE AT THE BOTTOM (A3)
CALLR COPY_ENTRY
INC A3
JRUC BUBBLE_ANOTHER
BUBBLE_DONE:
MOVE A3,A0 ;THIS IS BOTTOM OF TABLE
CALLR PT_ENTRY ;A7 POINTS AT CMOS BLOCK
MOVE *A8(TB_FACTORY),A6,L ;GET FACTORY TABLE
MOVI HS_ROM_SIZE,A1 ;SIZE OF ENTRY
MPYU A10,A1 ;TIMES NUMBER OF VALID ENTRIES..POINTS AT LAST.
ADD A1,A6 ;NOW WE POINT AT END OF ROM TABLE
MOVI HS_SIZE_IN_BYTES,A2 ;SIZE OF ENTRY
REPLACE_LOOP:
MOVB *A6,A0 ;MOVE A ROM BYTE TO A0
ADDI BYTE_SIZE,A6
CALLR WC_BYTEI ;WRITE THE WORD AND INCREMENT
DSJ A2,REPLACE_LOOP ;UNTIL THEY'RE ALL THERE.
MOVE A10,A0 ;POINT AT "LAST" ENTRY
CALLR FORM_HS_CKSUM_AND_STORE ;STORE THE CHECKBYTE
MMFM SP,A0,A1,A2,A6,A7 ;AND RETURN
RETS
**************************************************************************
* *
* CMOS UTILITIES *
* *
**************************************************************************
**************************************************************************
* *
* FOR ALL OF THESE CMOS ROUTINES. *
* *
* A7 = POINTER TO MEMORY *
* A0 = DATA TO/FROM MEMORY *
* *
**************************************************************************
*
* **** IMPORTANT NOTE ON WORD AND LONG WORD PACKING ****
* **** IMPORTANT NOTE ON WORD AND LONG WORD PACKING ****
* **** IMPORTANT NOTE ON WORD AND LONG WORD PACKING ****
* **** IMPORTANT NOTE ON WORD AND LONG WORD PACKING ****
* **** IMPORTANT NOTE ON WORD AND LONG WORD PACKING ****
*
* NOTE THAT REQUESTS FOR WORDS RETURN THE 2 BYTES PACKED
* INTO A WORD AS <1ST BYTE><2ND BYTE>. THIS IS NOT
* THE SAME WAY THAT THE GSP HANDLES A WORD POINTED AT
* WITH A POINTER.
*
* LONG WORDS WORK SIMILARLY:
*
* MSB LSB
* <1ST BYTE> <2ND BYTE> <3RD BYTE> <4TH BYTE>
*
* TOUGH LUCK INTEL HACKERS!
*
*
* RC_BYTE
* WC_BYTE
*
* These 2 routines are the only routines that ever touch
* CMOS ram. This is done to localize the effect of
* changes in the architecture. All efforts to deal with
* CMOS should come through these routines. Locking
* hardware will be easily added in the future (as well
* as different memory mapping).
*
RC_BYTE:
MOVB *A7,A0
ANDI BYTE_MASK,A0
RETS
WC_BYTE:
.IF YUNIT
MOVE A1,-*SP,L
MOVI 0200H,A1 ;UNLOCK THE CMOS
MOVE A1,@SECCHIP,W
.ENDIF
MOVB A0,*A7 ;WRITE OUT THE BYTE
.IF YUNIT
MOVI 0300H,A1 ;LOCK THE CMOS
MOVE A1,@SECCHIP,W
MMFM SP,A1
.ENDIF
RETS ;AND RETURN
**************************************************************************
* *
* RC_BYTEI *
* *
* READ BYTE POINTED TO BY A7...INCREMENT POINTER TO *
* "NEXT" BYTE. *
* *
**************************************************************************
RC_BYTEI:
CALLR RC_BYTE
ADDI C_BYTE_SIZE,A7 ;WORDS SEPARATE CMOS BYTES.
MOVE A0,A0 ;RETURN FLAGS ACCORDINGLY
RETS
RC_WORD:
MMTM SP,A1,A7 ;USE A1 TO COMBINE BYTES
CALLR RC_BYTEI ;GET A BYTE
MOVE A0,A1 ;SAVE IN A1
ANDI BYTE_MASK,A1 ;MASK ONLY BYTE
SLL 8,A1 ;SHIFT TO HIGH BYTE
CALLR RC_BYTE ;GET THE 2ND BYTE
ANDI BYTE_MASK,A0
OR A1,A0 ;A0 HAS THE WORD
MMFM SP,A1,A7
RETS
RC_WORDI:
CALLR RC_WORD
ADDI C_WORD_SIZE,A7 ;LONG SEPARATE CMOS WORDS.
MOVE A0,A0 ;RETURN FLAGS ACCORDINGLY
RETS
RC_LONG:
MMTM SP,A1,A7 ;USE A1 TO COMBINE BYTES
CALLR RC_WORDI ;GET A WORD
MOVE A0,A1 ;SAVE IN A1
ANDI WORD_MASK,A1 ;MASK ONLY WORD
SLL 16,A1 ;SHIFT TO HIGH WORD
CALLR RC_WORD ;GET THE 2ND WORD
ANDI WORD_MASK,A0
OR A1,A0 ;A0 HAS THE LONG WORD
MMFM SP,A1,A7
RETS
RC_LONGI:
CALLR RC_LONG
ADDI C_LONG_SIZE,A7 ;DOUBLE THE DISTANCE FOR BRAIN DAMIJ
MOVE A0,A0 ;RETURN FLAGS ACCORDINGLY
RETS
WC_BYTEI:
CALLR WC_BYTE
ADDI C_BYTE_SIZE,A7
RETS
WC_WORD:
MMTM SP,A0,A1,A7
MOVE A0,A1 ;MAKE COPY OF WORD
SRL 8,A0 ;GET HIGH BYTE IN A0
CALLR WC_BYTEI ;WRITE THE HIGH BYTE
MOVE A1,A0 ;NOW GET THE LOW BYTE BACK
CALLR WC_BYTE ;WRITE IT
MMFM SP,A0,A1,A7 ;AND RESTORE ALL WE TOUCHED
RETS
WC_WORDI:
CALLR WC_WORD
ADDI C_WORD_SIZE,A7
RETS
WC_LONG:
MMTM SP,A0,A1,A7
MOVE A0,A1 ;MAKE COPY OF LONG
SRL 16,A0 ;GET HIGH WORD IN A0
CALLR WC_WORDI ;WRITE THE HIGH WORD
MOVE A1,A0 ;NOW GET THE LOW WORD BACK
CALLR WC_WORD ;WRITE IT
MMFM SP,A0,A1,A7 ;AND RESTORE ALL WE TOUCHED
RETS
WC_LONGI:
CALLR WC_LONG
ADDI C_LONG_SIZE,A7
RETS
*****************************************************************************
*****************************************************************************
*****
***** DEFAULT ROM HSTD TABLES AND TABLE DEFINITIONS
*****
*****************************************************************************
*****************************************************************************
TB_POINTER EQU 0 ;LONG-POINTER TO BEGINNING OF TABLE
TB_COUNT EQU TB_POINTER+LONG_SIZE ;WORD....# IN THE TABLE.
TB_VISIBLE EQU TB_COUNT+WORD_SIZE ;WORD....NUMBER DISPLAYED
TB_PAGE_BITS EQU TB_VISIBLE+WORD_SIZE ;WORD....STATUS WORD FOR CMOS PAGE
TB_FACTORY EQU TB_PAGE_BITS+WORD_SIZE ;LONG....ROM STARTUP TABLE
TB_ERROR_COUNT EQU TB_FACTORY+LONG_SIZE ;WORD....NUM ERRORS TO RE-INIT
*
SCR_M $MACRO A,B,C,D
.BYTE :A:
.BYTE :B:
.BYTE :C:
.BYTE :D:
$END
INIT_M $MACRO A,B,C
.BYTE :A:
.BYTE :B:
.BYTE :C:
.BYTE 0 ;CHECKBYTE
$END
ALL_TIME_ROM_TABLE:
SCR_M 22H,12H,21H,45H ;****ZERO ENTRY...NOT SEEN!
INIT_M "E","P","J"
ROM_ENTRY_SIZE EQU $-ALL_TIME_ROM_TABLE
SCR_M 03H,05H,10H,48H
INIT_M "J","O","N" ;1
SCR_M 01H,84H,80H,00H
INIT_M "T","I","M" ;2
SCR_M 01H,79H,82H,18H
INIT_M "T","J","E" ;3
SCR_M 01H,75H,00H,72H
INIT_M "L","I","P" ;4
SCR_M 01H,69H,11H,96H
INIT_M "M","L","Z" ;5 ;LOCASIO
SCR_M 01H,65H,10H,08H
INIT_M "G","W","S" ;6
SCR_M 01H,60H,62H,33H
INIT_M "A","L","T" ;7
SCR_M 00H,57H,02H,18H
INIT_M "B","L","S" ;8
SCR_M 00H,50H,00H,01H
INIT_M "J","O","N" ;9
SCR_M 00H,45H,65H,71H
INIT_M "H","E","Y" ;10
SCR_M 00H,45H,01H,27H
ALL_TIME_ENTRIES EQU ($-ALL_TIME_ROM_TABLE)/ROM_ENTRY_SIZE
TODAYS_ROM_TABLE:
SCR_M 22H,12H,21H,45H ;****ZERO ENTRY...NOT SEEN!
INIT_M "E","P","J"
SCR_M 00H,20H,01H,27H
INIT_M "M","J","T"
SCR_M 00H,19H,01H,69H
INIT_M "D","R","J"
SCR_M 00H,10H,08H,65H
INIT_M "D","J","T"
SCR_M 00H,08H,21H,64H
INIT_M "N","L","N"
SCR_M 00H,05H,72H,18H
INIT_M "M","T","N"
SCR_M 00H,05H,12H,55H
INIT_M "T","L","C"
SCR_M 00H,04H,12H,50H
INIT_M "F","A","W"
SCR_M 00H,03H,19H,20H
INIT_M "F","O","O"
SCR_M 00H,02H,99H,44H
INIT_M "B","A","T"
SCR_M 00H,02H,57H,38H
INIT_M "M","A","N"
TODAYS_ENTRIES EQU ($-TODAYS_ROM_TABLE)/ROM_ENTRY_SIZE
.END