nba-jam-tournament-edition/HSTD.ASM

2032 lines
46 KiB
NASM
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

****************************************************************
*
* Software: LARRY DeMAR, EUGENE JARVIS
* Modified: Shawn Liptak 8/6/91 - Multi color fonts
*
* COPYRIGHT (C) 1991 WILLIAMS ELECTRONICS GAMES, INC.
*
*.Last mod - 12/22/92 17:49
****************************************************************
.file "hstd.asm"
.title "robo high-score-to-date management"
.width 132
.option b,d,l,t
.mnolist
.include "mproc.equ"
.include "disp.equ"
.include "sys.equ"
.include "game.equ"
.include "imgtbl.glo"
.include "link.equ"
.include "shawn.hdr" ;Macros
.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
;RJR .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
.def INITMAT
* OTHER MODULES
.REF RD15FONT,SYSCOPY,P1DATA,P2DATA
.REF BINBCD,FON150
; .REF AFONT0,GOGO
* HELP.ASM
.REF DEF_PAGE,GET_ADJ
.TEXT
;Sound headers
BEEPSND .WORD >F3FE,>10,>80A2,0 ;LOW BEEP
**************************************************************************
*
* HIGH SCORE TABLE DEFINITIONS
*
**************************************************************************
;RJR
.if 0
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
.endif
P_FORK
MMTM SP,A1
MOVE *A13(PROCID),A1 ;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. Z set if 0
*
**************************************************************************
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
;RJR
.if 0
movi ALL_TIME_SELECT,a1
callr SET_PAGE
movi [62,27],a10 ;Screen start address
movi ALL_TIME_ORIGIN+HS_INITS+HS_SIZE,a8 ;Table start address
JSRP HSINITDSP
movi [62,63],a10
movi ALL_TIME_ORIGIN+HS_SCORE+HS_SIZE,a8
JSRP HSNUMDSP
movi TODAYS_SELECT,a1
CALLR SET_PAGE
movi [62,227],a10
movi TODAYS_ORIGIN+HS_INITS+HS_SIZE,a8
JSRP HSINITDSP
movi [62,263],a10
movi TODAYS_ORIGIN+HS_SCORE+HS_SIZE,a8
JSRP HSNUMDSP
.endif
RETP
********************************
* DISPLAY SCORE TABLE SCORES IN ATTRACT
* A8=TABLE INDEX
* A10=DISPLAY COORD Y:X
HSNUMDSP
movk 10,a11 ;# scores
movi >1010101,a9 ;Start color 1, pal 1
hsn10 move a8,a7
callr RC_LONG ;GET THE SCORE=A0
move a7,a8
move a10,a3 ;Dest Y:X
clr a6 ;Blanking ON
move a12,-*sp,L
movk 8,a12
callr HSNUML0
move *sp+,a12,L
SLEEPK 1
addi HS_SIZE,a8
addi >120000,a10 ;Next line
dsj a11,hsn10
RETP
********************************
* DMA a BCD number (Trashes A0-A1)
* A0=#
* A3=Y:X
* A6=Blank flag (0=ON)
* A9=Color:Pal
* A12=#Digits
*Rets:
* A9=Next Color:Pal
HSNUML0
mmtm sp,a2,a3,a4,a5,a7,a8,a10,a11
move a0,a11
srl 4*3,a0
jrz hsnlp ;No comma?
subk 6,a3 ;-X
hsnlp move a11,a1
srl 28,a1 ;Next digit value into lowest 4 bits
jrnz hsn5
move a6,a6
jrz hsn50 ;Skip digit if blanking
hsn5 cmpi 3,a12
jrnz hsn13
move a6,a6
jrz hsn13 ;1st non zero?
move a1,-*sp
movi RD15FONT+11*32,a1 ;Comma
move *a1,a1,L
move a3,a10
addi >b0000,a3 ;+Y
callr font_dma
move a10,a3
addk 6,a3 ;+X
move *sp+,a1
hsn13 cmpi 9,a1
jrls hsn15 ;Digit ok?
movk 9,a1 ;Output 9 on an error
hsn15 movk 1,a6 ;Blanks off
move a3,a10
cmpi 1,a1
jrnz hsn30
addk 3,a3 ;Offset 1's X
hsn30 movi 32*4+16,a0
mpyu a0,a1 ;*Header size
addi FON150,a1 ;Base address of image header
callr font_dma
move a10,a3
hsn50 addk 14,a3 ;step to next
sll 4,a11 ;next digit
dsj a12,hsnlp
addi >f0f0000,a9
cmpi >30300000,a9
jrls hsnx
addi >101,a9 ;Next PAL
zext a9
addi >1010000,a9 ;Color 1
hsnx mmfm sp,a2,a3,a4,a5,a7,a8,a10,a11
rets
********************************
* DMA a character
* A1=*Obj header
* A3=Y:X
* A9=Color:Pal
* Trashes A0-A5,A7-A8,A14
font_dma
move *a1(ISAG),a4,L
move *a1(ICTRL),a5
move *a1+,a2 ;Get X size
move a5,a7
sll 32-15,a7 ;Get bits 12-14
srl 32-15+12,a7
mpyu a2,a7
; addk 3,a7 ;Round up to 4 bit boundary
; srl 2,a7
; sll 5,a7 ;X size*8
addi >10000,a2 ;Y Size 1
move *a1+,a8 ;Get Y size
ori DMACNZ,a5
move a9,a1
fdlp calla QDMAN
addi >1010000,a1 ;Next color
add a7,a4 ;Set SAG for next line
addi >10000,a3 ;Y+1
dsj a8,fdlp
rets
********************************
* DISPLAY SCORE TABLE INITIALS IN ATTRACT
* A8=TABLE INDEX
* A10=DISPLAY COORD Y:X
HSINITDSP
movk 10,a11 ;10 Scores
hsid10 move a8,a7
subi HS_INITS,a7
callr RC_LONG ;Get the score in a0
move a0,a2
addi HS_INITS,a7
move a10,a3 ;Y:X
movi >01010101,a1 ;Flash if inits match score
callr A2_CHECK
jrz hsid30
movi >1f1f0303,a1 ;Color:pal
hsid30 move a12,-*sp,L
movk 3,a12
hsid50 callr RC_BYTE ;Get initial
addk 16,a7 ;Step to next initial
callr initout ;Output initial
dsj a12,hsid50
move *sp+,a12,L
addi >120000,a10 ;Next Y
move a7,a8
SLEEPK 1
addi HS_SIZE-48,a8 ;Get next guy in cmos
dsj a11,hsid10
RETP
********************************
* Output initial in RD15FONT
* A0=ASCII
* A1=COLOR:PALETTE
* A3=Y:X
* Trashes A0
*Rets:
* A3=New Y:X
initout
mmtm sp,a1,a2,a4,a5,a7,a8,a9,a10,a11,a14
subi >21,a0 ;Start of table
cmpi >7d->21,a0
jrhi inox
sll 5,a0
addi RD15FONT,a0
move *a0,a0,L ;Get pointer
move *a0(ISAG),a4,L
move *a0(ICTRL),a5
move *a0+,a2 ;Get X size
move a5,a7
sll 32-15,a7 ;Get bits 12-14
srl 32-15+12,a7
mpyu a2,a7
; addk 3,a7 ;Round up to 4 bit boundary
; srl 2,a7
; sll 5,a7 ;X size*8
movk 12,a9
sub a2,a9
sra 1,a9 ;/2
add a9,a3 ;Add X offset so letter centered
addi >10000,a2 ;Y Size 1
move *a0+,a8 ;Get Y size
clr a11 ;A11=Line cnt
move a3,a10
ori DMACNZ,a5
inolp calla QDMAN
addk 1,a11
cmpi 15,a11
jrge ino50 ;Out of colors?
addi >1010000,a1 ;Next color
ino50 add a7,a4 ;Set SAG for next line
addi >10000,a3 ;Y+1
dsj a8,inolp
move a10,a3
sub a9,a3
inox addk 17,a3
mmfm sp,a1,a2,a4,a5,a7,a8,a9,a10,a11,a14
rets
********************************
*OUTPUT INITIAL RD15FONT
*A0=ASCII
*A1=COLOR:PALETTE
*A3=COORD Y:X
INITOUT
PUSH a2,a4,a5,a14
subi >21,a0 ;Start of table
cmpi >7d->21,a0
jrhi initerr
sll 5,a0
addi RD15FONT,a0
move *a0,a0,L ;Get pointer
move *a0,a2,L ;Get size
movk 12,a4
subxy a2,a4
sext a4
sra 1,a4 ;/2
add a4,a3 ;Add X offset so letter centered
move a4,-*sp
move *a0(ISAG),a4,L
move *a0(ICTRL),a5
ori DMACNZ,a5
calla QDMAN
move *sp+,a0
sub a0,a3
initerr addk 17,a3
PULL a2,a4,a5,a14
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 ;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
;RJR
.if 0
MMTM SP,A8,A10
MOVK 1,A0
MOVE @P1DATA,A8,L ;FIX!
MOVE @P2DATA,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
.endif
********************************
*TIMER FOR INITIAL PROCESS
.BSS INITTIMR,16
.BSS GET1FLG,16
.BSS GET2FLG,16
INITTIM
CLR A0
MOVE A0,@GET1FLG
MOVE A0,@GET2FLG
CREATE HISC_PID,INTIML
MOVI 30,A1
MOVE A1,@INITTIMR
MOVE A1,*A0(PA10),L ;SET A10 TO 60
RETS
INTIML
MOVE @INITTIMR,A0
DEC A10
JRNE INTIML1
MOVI 60,A10
DEC A0
JRN INITTIMX
MOVE A0,@INITTIMR
INTIML1 CALLA BINBCD
MOVI [19,194],A3
MOVE A12,-*SP,L
MOVK 2,A12
MOVK 1,A6
SLL 24,A0 ;SHIFT DIGITS INTO PLACE
movi >1010101,a9
callr HSNUML0
MOVE *SP+,A12,L
SLOOP 1,INTIML
INITTIMX
DIE
********************************
*GET PLAYERS INITIALS - WAIT TILL DONE
GETINIT
SLEEPK 10
CALLR DONCK
JRNE GETINIT
GETINITX
SLEEP 60 ;WAIT A SEC. THEN BOOK
RETP
********************************
*CHECK IF INITIALS DONE
DONCK
MOVE @INITTIMR,A2
JREQ DONCKX
MOVE @GET1FLG,A0
MOVE @GET2FLG,A1
ADD A0,A1
DONCKX RETS
********************************
*GET PLAYER 1 INITIALS
GETINIT1
; MOVI P1ITAB,A0
; MOVI LTRBOX1,A2 ;(OIMG) ;SHELL PROGRAM
; JRUC GTINIT
;P1ITAB
; .LONG P1DATA ;SCORE VALUE FIX!
; .byte " ",0
; .LONG >00000000 ;START BOX COORD
; .IF YUNIT
; .LONG SWITCH,SWITCH+4,SWITCH+18 ;SWITCH LOCATIONS
; .ELSE
; .LONG SWITCH,SWITCH+8,SWITCH+24
; .ENDIF
; .LONG >002c0030 ;INITIAL DISPLAY ADDRESS
; .LONG >3b3b0000 ;COLOR:PALETTE
; .LONG GET1FLG
********************************
*GET PLAYER 2 INITIALS
GETINIT2
; MOVI P2ITAB,A0
; MOVI LTRBOX2,A2 ;OIMG
; JRUC GTINIT
;P2ITAB
; .LONG P2DATA ;SCORE VALUE FIX!
; .byte " ",0
; .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 >002c0124 ;INITIAL DISPLAY ADDRESS
; .LONG >3b3b0000 ;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 Y:X
*PDATA+>60=MOVE STICK ADDRESS
*PDATA+>80=FIRE STICK ADDRESS
*PDATA+>A0=START BUTTON ADDRESS
*PDATA+>C0=INITIALS DISPLAY Y:X OFFSET
*PDATA+>E0=COLOR:PALETTE INITIAL
*PDATA+>100=INITIAL DONE FLAG (DONE=0)
;RJR
.if 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
clr a5 ;(OID)
CLR A6 ;(OXVEL)
CLR A7 ;(OYVEL)
CALLA BEGINOBJ
GTL CMPI 3,A11 ;GET MOVE SWITCHES
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) ;SAVE COORDS
MOVE A1,*A13(PDATA+>50)
*FORM BOX XY COORD AND UPDATE IT
GTL5 MOVE *A13(PDATA+>40),A0 ;Get X
MOVE *A13(PDATA+>50),A1 ;Get Y
movk 21,a3
movk 22,a5
MPYU A0,A3 ;FORM X OFFSET
MPYU A1,A5 ;FORM Y OFFSET
move @WORLDTLX+16,a2
add a2,a3
addi 137,a3
move @WORLDTLY+16,a2
add a2,a5
addi 41,a5
MOVE A3,*A8(OXPOS) ;UPDATE POSITION
MOVE A5,*A8(OYPOS)
*UPDATE YOUR LETTER VALUE
*A0=X OFFSET
*A1=Y OFFSET
MOVK 6,A3
MPYU A1,A3
ADD A0,A3 ;THIS IS THE INDEX TO MATRIX
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
MOVI BEEPSND,A0
CALLA snd_play1
MOVK >20,A0
MOVB A0,*A4 ;THROW OUT A SPACE
JRUC GTL4
GTL3A
MOVI BEEPSND,A0
CALLA snd_play1
INC A11
CMPI 3,A11
JRLO GTL4
GTL3X
CALLA DELOBJA8
MOVE *A13(PDATA+>100),A0,L
CLR A1
MOVE A1,*A0 ;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
ADDK >16,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
SLEEPK 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
.endif
********************************
*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,A0,L ;FIX!
CMP A2,A0
JREQ A2_SUCC ;IT WAS PLAYER 1'S SCORE
MOVE @P2DATA,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
* WON'T 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
;RJR
.if 0
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
.endif
RETS
**************************************************************************
*
* INIT_TB
*
* THIS IS CALLED TO SETUP A HIGH SCORE TABLE WITH
* FACTORY ENTRIES.
*
* A8 = ROM TABLE POINTER
*
**************************************************************************
INIT_TB:
;RJR
.if 0
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
.endif
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 ****
*
* 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
.if TUNIT
move @SYSCOPY,a0
sll 32-8,a0
srl 32-2,a0
sll 15,a0 ;Page offset
add a7,a0
movb *a0,a0
sll 32-8,a0
srl 32-8,a0
rets
.else
movb *a7,a0
sll 32-8,a0
srl 32-8,a0
rets
.endif
WC_BYTE
.IF YUNIT
MOVE A1,-*SP,L
MOVI 0200H,A1 ;UNLOCK THE CMOS
MOVE A1,@SECCHIP
.ENDIF
.if TUNIT
move @SYSCOPY,a1
sll 32-8,a1
srl 32-2,a1
sll 15,a1 ;Page offset
add a7,a1
move a0,@CMOSWE
movb a0,*a1
.else
movb a0,*a7 ;Write byte
.endif
.IF YUNIT
MOVI 0300H,A1 ;LOCK THE CMOS
MOVE A1,@SECCHIP
MMFM SP,A1
.ENDIF
rets
**************************************************************************
*
* 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
SCRM .MACRO a,b
.byte :a:/>1000000,:a:/>10000&>ff,:a:/>100&>ff,:a:&>ff
.byte ":b:",0
.ENDM
ALL_TIME_ROM_TABLE
SCRM >22122145,"EPJ" ;****ZERO ENTRY...NOT SEEN!
ROM_ENTRY_SIZE EQU $-ALL_TIME_ROM_TABLE
SCRM >484692,"MJT"
SCRM >434010,"SL!"
SCRM >366892,"JON"
SCRM >296096,"SYD"
SCRM >265237,"HEY"
SCRM >215782,"EJB"
SCRM >182074,"DRJ"
SCRM >146892,"PJS"
SCRM >130523,"GNP"
SCRM >118913,"TIM"
ALL_TIME_ENTRIES EQU ($-ALL_TIME_ROM_TABLE)/ROM_ENTRY_SIZE
TODAYS_ROM_TABLE
SCRM >22122145,"EPJ" ;****ZERO ENTRY...NOT SEEN!
SCRM >111111,"SL!"
SCRM >94477,"EPJ"
SCRM >80486,"LED"
SCRM >70882,"DAN"
SCRM >68040,"DJT"
SCRM >59104,"JPW"
SCRM >40450,"NED"
SCRM >38780,"MJT"
SCRM >28088,"BUY"
SCRM >16502,"WMS"
TODAYS_ENTRIES EQU ($-TODAYS_ROM_TABLE)/ROM_ENTRY_SIZE
.END