Jump to content
IGNORED

VCS Skeleton Kernel - Source


Curt Vendel

Recommended Posts

.title VCS Skeleton Program

.enable ama

.asect ;absolute addressing

.radix 16 ;default base

.LIST MEB ;DISPLAY ALL OF ANY MACROS

;

romstr = 0f000 ;rom start addr

; SKLTON.MAC

; copyright Atari, 1982

.nlist

.sbttl Stella Hardware Regs

.list

.page

; *

; **

;********** **********************************

;*********** * TIA and PIA Register Addresses *

;********** **********************************

; **

; *

 

 

;

; TIA Addresses

vsync = 00 ;bit 1 vertical sync set-clr 1=>start

vblank = 01 ;bit 76 1 vblank set-clr, port ctl (inpt0-5)

wsync = 02 ;strobe wait for horiz blank

rsync = 03 ;strobe reset horiz sync counter

nusiz0 = 04 ;bits 54 210 number-size player/missile 0

nusiz1 = 05 ;bits 54 210 number-size player/missile 1

colup0 = 06 ;bits 7654321 color(4)-lum(3) player 0

colup1 = 07 ;bits 7654321 color(4)-lum(3) player 1

colupf = 08 ;bits 7654321 color(4)-lum(3) playfield

colubk = 09 ;bits 7654321 color(4)-lum(3) background

ctrlpf = 0a ;bits 54 210 playfield control & ball

refp0 = 0b ;bit 3 reflect player 0. 1=>reflect

refp1 = 0c ;bit 3 reflect player 1

pf0 = 0d ;bits 7654 playfield reg byte 0 (reversed)

pf1 = 0e ;bits all playfield reg byte 1

pf2 = 0f ;bits all playfield reg byte 2 (reversed)

resp0 = 10 ;strobe reset player 0

resp1 = 11 ;strobe reset player 1

resm0 = 12 ;strobe reset missile 0

resm1 = 13 ;strobe reset missile 1

resbl = 14 ;strobe reset ball

audc0 = 15 ;bits 3210 audio control 0

audc1 = 16 ;bits 3210 audio control 1

audf0 = 17 ;bits 3210 audio frequency 0

audf1 = 18 ;bits 3210 audio frequency 1

audv0 = 19 ;bits 3210 audio volume 0

audv1 = 1a ;bits 3210 audio volume 1

grp0 = 1b ;bits all graphics for player 0

grp1 = 1c ;bits all graphics for player 1

enam0 = 1d ;bit 1 enable missile 0. 1=> enable

enam1 = 1e ;bit 1 enable missile 1

enabl = 1f ;bit 1 enable ball

hmp0 = 20 ;bits 7654 horiz motion player 0. 0-7 => left

hmp1 = 21 ;bits 7654 horiz motion player 1. f-8 => right

hmm0 = 22 ;bits 7654 horiz motion missile 0

hmm1 = 23 ;bits 7654 horiz motion missile 1

hmbl = 24 ;bits 7654 horiz motion ball

vdelp0 = 25 ;bit 0 vertical delay player 0. 1=> vdel on

vdelp1 = 26 ;bit 0 vertical delay player 1

vdelbl = 27 ;bit 0 vertical delay ball

resmp0 = 28 ;bit 1 reset missile to player 0

resmp1 = 29 ;bit 1 reset missile to player 1

hmove = 2a ;strobe act on horiz motion

hmclr = 2b ;strobe clear all hm registers

cxclr = 2c ;strobe clear collision latches

;

; Read Addresses - bits 7 & 6 only

cxm0p = 30 ;m0*p1 m0*p0

cxm1p = 31 ;m1*p0 m1*p1

cxp0fb = 32 ;p0*pf p0*bl

cxp1fb = 33 ;p1*pf p1*bl

cxm0fb = 34 ;m0*pf m0*bl

cxm1fb = 35 ;m1*pf m1*bl

cxblpf = 36 ;bl*pf

cxppmm = 37 ;p0*p1 m0*m1

inpt0 = 38 ;pot 0. bit7=1 => pot cap is charged

inpt1 = 39 ;pot 1

inpt2 = 3a ;pot 2

inpt3 = 3b ;pot 3

inpt4 = 3c ;joystick 0 button. b7=0 => button pressed

inpt5 = 3d ;joystick 1 button

;

; PIA and Timer (6532) Locations

swcha = 280 ;p0,p1 sticks (rldu), pot triggers, kbd, driving ctl

ctlswa = 281 ;swcha i/o control 1=output

swchb = 282 ;console switches (read only) p1b,p0b,x,x,b/w,x,select, reset

ctlswb = 283 ;unused

intim = 284 ;interval timer input =>timer up

tim1t = 294 ;timer output: 1 mc/tick (.838 microsec)

tim8t = 295 ;8 machine cycles/tick

tim64t = 296 ;64 mc's/tick

t1024t = 297 ;1024 machine cycles/tick (858.2 microseconds)

.nlist

.sbttl Equates

.list

.page

; *

; **

;********** ********************

;*********** * Assorted Equates *

;********** ********************

; **

; *

 

 

gscon = 45. ;game select timer initial value

ovrcon = 25 ;overscan timer initial value

vblcon = 2b ;vblank timer initial value

gmax = 03 ;highest game # +1

.nlist

.sbttl Ram Variables

.list

.page

; *

; **

;********** *****************************

;*********** * Variables (ram page zero) *

;********** *****************************

; **

; *

 

 

.=80

tcol: .=.+1 ;top score color

bcol: .=.+1 ;bottom score color

gflg1: .=.+1 ;game status bits

;80 1= game is in play

;40 1= bonzo (easy) game

;20 1= one-player game

;10 1= select mode

;08 1= color-shifting attract mode

;04 not used yet

;02 not used yet

;01 not used yet

gamno: .=.+1 ;game number (decimal)

gstim: .=.+1 ;game select timer

tscr: .=.+2 ;top player's score

bscr: .=.+2 ;bottom player's score

rand: .=.+1 ;"random" number seed/last number

rndind: .=.+1 ;"random" number index

frame: .=.+1 ;frame counter

hfram: .=.+1 ;hi byte of frame counter

atim: .=.+1 ;attract timer

atmask: .=.+1 ;attract lum mask

t0: .=.+1 ;temporary variables

t1: .=.+1

.NLIST

.SBTTL MACROS

.LIST

.PAGE

; *

; **

;********** ******************

;*********** * MACROS *

;********** ******************

; **

; *

;

; PALIGN WILL AUTOMATICALLY ALIGN FOLLOWING CODE WITH A PAGE VOUNDARY.

; IT WILL USUALLY BE USED AT THE TOP OF TABLES, SO THAT A TABLE WON'T

; CROSS A BOUNDARY AND FUCK UP A KERNEL.

;

.MACRO PALIGN

.=<.+0FF>&0FF00

.ENDM

;

;

; .INTSET ENABLES INTERRUPTS WHEN IN A RAM VERSION, BUT ALLOWS INTERRUPTS

; TO BE DISABLED IN THE ROMMED VERSION, BY THE USE OF THE TERM ZZZROM.

; AS LONG AS ZZZROM IS UNDEFINED, INTERRUPTS WILL BE ENABLED, AND A

; PROGRAM CAN BE HALTED BY CONTROL-C. BEFORE ROMMING THE PROGRAM, MERELY

; INSERT A DEFINITION FOR ZZZROM, SUCH AS ZZZROM = 1.

;

.MACRO .INTSET

.IF NDF,ZZZROM

CLI

.IFF

SEI

.ENDC

.ENDM

;

;

; LINE WILL DECREMENT THE LINE COUNT, IF REQUESTED, WILL SET UP A

; PLAYER, IF REQUESTED, AND WILL SET UP A MISSILE OR BALL DURING A

; KERNEL LINE. THE LINE COUNT MAY BE DECREMENTED BY ANY VALUE, SET

; AS ARGUMENT A1. IF A1 IS ZERO, THAT PART OF THE CODE IS NOT

; ASSEMBLED. ARGUMENT A2 SPECIFIES THE VERTICAL POSITION OF THE

; PLAYER, BY NAME OF RAM POSITION WHERE THAT VALUE IS LOCATED. IF

; THAT ARGUMENT IS SET TO ZERO, THE CODE FOR HANDLING THE PLAYER

; IS LEFT OUT.

;

; THERE ARE EIGHT ARGUMENTS, BUT A8 MUST NOT BE SPECIFIED WHEN

; INVOKING THE MACRO. IT IS A DUMMY FOR CREATING A JUMP ADDRESS.

; THE OTHERS MUST BE USED, AT LEAST TO THE POINT OF PUTTING IN A

; COMMA AS A PLACE-HOLDER. THE ARGUMENTS AND THEIR MEANINGS ARE:

;

; A1 LINE COUNT DECREMENT AMOUNT (USUALLY 1 OR 2; IF 0, CODE IS

; SKIPPED)

; A2 NAME OF RAM LOCATION FOR VERT. POSITION OF A PLAYER. IF 0,

; CODE FOR PLAYER SETUP IS LEFT OUT

; A3 PLAYER'S HEIGHT

; A4 NAME OF PLAYER'S GRAPHICS TABLE

; A5 NAME OF A TEMPORARY STORAGE LOCATION FOR THAT PLAYER'S GRAPHICS

; A6 NAME OF LOCATION FOR MISSILE'S OR BALL'S VERTICAL POSITION

; A7 HEIGHT OF MISSILE OR BALL

; A8 DUMMY JUMP ADDRESS -- DON'T PUT A VALUE IN FOR THIS ARGUMENT!!!

;

; AN EXAMPLE FOR THE FIRST LINE OF A DOUBLE-LINE KERNEL MIGHT BE:

;

; LINE 2,VP0,8,P0TAB,GP0,VM0,14.

;

; THE SECOND LINE OF THE KERNEL MIGHT LOOK LIKE:

;

; LINE 0,VP1,10.,P1TAB,GP1,VBL,4

;

; A LINE WITH NO PLAYER MIGHT BE CALLED AS FOLLOWS:

;

; LINE 1,0,,,,VM1,6

;

; NOTE THAT ALL NUMERIC VALUES ARE IN HEX, AND DECIMAL VALUES MUST END

; WITH A DOT. THIS MACRO USES THE ACCUMULATOR AND Y REGISTER, BUT LEAVES

; THE X REGISTER FREE.

;

; THE RESULTS OF THIS MACRO MUST BE INVOKED AT THE START OF THE NEXT LINE,

; PROBABLY IMMEDIATELY AFTER AT STA WSYNC, OR AFTER STA WSYNC, STA HMOVE.

; IF THE PLAYER GRAPHICS HAS BEEN STORED IN GP1, FOR INSTANCE, AND YOU

; ARE ABOUT TO PUT UP THAT PLAYER AND THE BALL, AS IN THE SECOND EXAMPLE

; ABOVE, YOU WOULD PUT IN CODE:

; STY ENABL

; LDY GP1

; STY GRP1

; AND THEN CONTINUE WITH REST OF CODE FOR THAT LINE. THERE SHOULD BE

; ENOUGH TIME TO GET A PLAYFIELD STARTED, BUT DON'T DECREMENT LINE

; COUNTS WHERE THERE WILL BE NEW PLAYFIELD. THERE ISN'T ENOUGH TIME.

; PUT A 0 IN A1 FOR THOSE LINES, IN A TWO-LINE KERNEL, AND PUT A 2 IN

; A1 ON THE NEXT LINE, WHERE THERE WILL BE MORE TIME.

;

; THE ROUTINE WALKS DOWN THROUGH THE PLAYER GRAPHICS TABLE AS IT MOVES

; DOWN THE SCREEN, SO THE FIRST VALUE OF THE TABLE SHOULD BE 0, TO SET

; THAT VALUE INTO THE GRAPHICS STORE LOCATION WHEN THE PLAYER ISN'T TO

; APPEAR.

;

.MACRO LINE A1,A2,A3,A4,A5,A6,A7,?A8

.IF NE,A2

LDA A2

SEC

SBC LNCNT

CMP #A3

BCS A8

TAY

LDA A4(Y)

STA A5

.ENDC

A8: LDY #0

LDA LNCNT

SEC

.IF NE,A1

SBC #A1

STA LNCNT

.ENDC

SBC A6

CMP #-A7

BCC .+4

LDY #2

.ENDM

;

;

.nlist

.sbttl Initialization

.list

.page

; *

; **

;********** ******************

;*********** * Initialization *

;********** ******************

; **

; *

 

 

.=romstr

init: sei ;disable interrupts

cld ;binary arithmetic

ldx #0

txa

sta ctlswa ;set porta for input

10$: sta 0(x) ;clear hardware registers and ram

inx

bne 10$

dex ;ff

stx gflg1 ;set select mode flag

txs ;init stack ptr

;

; Perform a Game Select, Game # 1

;

jsr initsl ;simulate select lever press

;

; End of Initialization

;

jmp oversc ;go start with overscan

.nlist

.sbttl video kernel

.list

.page

; *

; **

;********** ****************

;*********** * Video Kernel *

;********** ****************

; **

; *

 

 

kernel: sta wsync ;0

lda #82 ;2 load background color

eor atim ;5 comp for attract mode

and #0f7 ;7

sta colubk ;10

ldx #180. ;12 load number of lines

10$: sta wsync ;0 finish the line

dex ;2 done?

bne 10$ ;4,5 no, go

lda gflg1 ;7 are we in select mode?

and #10 ;9

bne copy ;11,12 yes, go do copyright notice

ldx #11. ;13 load number of lines

20$: sta wsync ;0 end the line

dex ;2 done?

bne 20$ ;4,5 no, go

jmp oversc ;7 yes, exit

;

; Display Copyright Notice

;

copy: sta wsync ;0 sync up

stx pf0 ;3 clear playfield regs

stx pf1 ;6

stx pf2 ;9

nop ;11 waste some cycles

sta t0 ;14 waste some more

lda bcol ;17 set up player color

eor atim ;20 adjust for attract colors

and atmask ;23 ensure low lum if attract colors

sta colup0 ;26

sta colup1 ;29

nop ;31 waste 2 cycles here

lda #0f0 ;33 set up fine positioning in advance

sta hmp0 ;36

ldx #0 ;38

stx hmp1 ;41

sta resp0 ;44 reset player zero...

sta resp1 ;47 ...and player one

sta wsync ;0

sta hmove ;3 execute fine adjustment

lda #0cb ;5 set nusiz for small players

sta nusiz0 ;8 and proper number of copies

ldx #1 ;10

stx nusiz1 ;13

; do display

ldx #07 ;15 for 8 lines of the screen...

1$: stx t1 ;18,66 save index because x is used later

sta wsync ;0

ldy #2 ;2 time out to center of screen

dey ;4;9

bne .-1 ;7;11

sta t0 ;14 waste 3 cycles to get timing right

lda col1-1(x) ;18 get graphics for first store

sta grp0 ;21 store it

lda col2-1(x) ;25 same for p1

sta grp1 ;28

ldy col3-1(x) ;32 now get tricky to save time...

lda col4-1(x) ;36 use X and Y and A to their fullest

sta t0 ;39 use temp 0 also for time savings

lda col5-1(x) ;43 now load up all 3 regs

ldx t0 ;46

sty grp0 ;49 and store 'em as fast as possible

stx grp1 ;52 (timing is very crucial here)

sta grp0 ;55

ldx t1 ;58 now restore index

dex ;60

bne 1$ ;62,63 and branch back till done

stx grp0 ;65 clear player graphics for neatness

stx grp1 ;68

sta wsync ;0 display two blank lines

sta wsync ;0 (bottom margin)

jmp oversc

;

; End of Kernel

;

.nlist

.sbttl Overscan

.list

.page

; *

; **

;********** ***************************

;*********** * Overscan: 30 Scan Lines *

;********** ***************************

; **

; *

 

 

;

; Tie Up Screen Loose Ends

;

oversc: ldx #0

stx colubk ;turn off background

lda #ovrcon ;set up overscan timer

sta tim64t

lda #82 ;turn on vblank, ground the pots

sta vblank

;

; Update Frame Counter

;

inc frame

bne 10$ ;go if no overflow

inc hfram

lda #30 ;time to go into attract?

cmp hfram

bne 10$ ;no, go

lda gflg1 ;yes, set the flag

ora #08

sta gflg1

10$:

;

; Check For Reset/Game Select

;

jsr gsrst ;check levers...

bcs 99$ ;if lever was pressed...

jmp intst ;skip game play this frame

99$:

;

;

;********************************************

; put overscan calcs here *

;********************************************

;

;

;

; End of Overscan

;

intst: ldx intim ;overscan done yet?

bne intst ;no, go back

vsnc: ldx #02 ;yes, do vsync

stx vsync

sta wsync ;send 4 lines of vsync

sta wsync

sta wsync

sta wsync

lda #0

sta vsync ;turn off vsync (a=0)

.nlist

.sbttl Vblank Calculations

.list

.page

; *

; **

;********** *************************

;*********** * Vblank: 37 Scan Lines *

;********** *************************

; **

; *

 

 

;

; Start Vblank Timer

;

vblnk: lda #vblcon ;set up vblank timer

sta tim64t

;

;

;********************************************

; put vblank calcs here *

;********************************************

;

;

; Color-Shift Attract Mode

;

shft: ldy #0ff ;assume no attract mask

lda gflg1 ;are we in color attract?

and #08

bne 5$ ;yes, go

sta atim ;no, reset attract shift key to zero

beq 99$ ;always taken

5$: ldy #0f7 ;load attract mask

lda frame ;is it time to shift?

bne 99$ ;no, go

inc atim ;set new color-shift mask

99$: sty atmask ;store current lum mask

;

; End of Vblank

;

intst2: lda intim ;done with vblank yet?

bne intst2 ;no, go back

sta wsync ;yes, get ready for kernel

sta vblank ;turn off vblank, and start charging pots

sta hmclr ;reset horiz. motion regs to 0

sta cxclr ;clear collisions

jmp kernel ;go for it

.nlist

.sbttl Game Reset/Select

.list

.page

; *

; **

;********** ******************************

;*********** * Game Select and Game Reset *

;********** ******************************

; **

; *

 

 

; Check to see if game select or game reset levers are being

; pressed. If yes, then check to see if time-out has occurred. If

; yes, then execute the function. Otherwise return with carry set,

; indicating that no action was taken. If game select or reset did

; take place, return with carry clear, so that the overscan calcs will

; be skipped (reset or select usually takes a long time to do).

gsrst: lda swchb ;read console switches

ror

bcc grs ;go if reset lever pressed

gs2: ror

bcc gsel ;go if game select lever pressed

ldx #1

stx gstim

gsex: sec

rts ;rts with carry set means no action

;

; Game Select

gsel: dec gstim ;time to execute?

bne gsex ;no, go

initsl: lda #2d ;reset timer

sta gstim

lda gflg1 ;are we in select mode?

and #10

beq 12$ ;no, don't inc game number

sed ;new game number

lda gamno

clc

adc #1 ;add 1 to old number

cmp #gmax ;too high?

bne 10$ ;no, skip reset

lda #1 ;yes, reset to 1

10$: sta gamno

cld ;restore binary functioning

;***************************************

; put game select logic here *

;***************************************

12$: ldx gamno ;set gflg1 from table

lda gf1sel-1(x)

sta gflg1

bne gsrs ;always taken

;

; Game Reset

grs: dec gstim ;time to execute?

bne gsex ;no, exit

ldx #10 ;reset timer

stx gstim

ldx gamno ;set gflg1 from table

lda gf1rst-1(x)

sta gflg1

;**************************************

; put game reset logic here *

;**************************************

ldx #0 ;reset scores

stx tscr

stx tscr+1

stx bscr

stx bscr+1

;

; Both Functions

gsrs: lda #05 ;set up hardware

sta nusiz0

sta nusiz1

lda #21

sta ctrlpf

lda #4

sta audc0

sta cxclr

lda #0

sta hfram ;turn off color attract

ldx #1 ;set up screen colors

20$: lda misc(x)

sta tcol(x)

dex

bpl 20$

99$: clc ;return with clear carry

rts

.nlist

.sbttl Assorted Subroutines

.list

.page

; *

; **

;********** ************************

;*********** * Assorted Subroutines *

;********** ************************

; **

; *

 

 

;

; "Random" Number Routine

;

; Returns a "random" number in the accumulator. If it doesn't

; seem very random try playing around with the base address of the first

; two exclusive or's... find very varied pieces of your program to use,

; and it should return very unpredictable results. Another trick is to

; somehow do an eor with your game controllers... this is about

; as random as data can get, and usually makes a difference.

rndno: lda rand ;get seed (last number)

ldx rndind ;and index

eor oversc(x) ;"randomize"

eor kernel(x)

asl ;rotate to avoid single-bit

adc #0 ;state preferences

inx

stx rndind ;save new index

eor hfram ;and use frame counter for

eor frame ;long repeat time

sta rand ;save new seed

rts ;exit

;

; Score Addition Routine

;

; Adds value found in accumulator to the player whose offset is in

; y-reg. Keep in mind that player zero should be y-reg = 0 and player

; one should be y-reg = 2. Also, remember the amount to add (in the acc.)

; should be a decimal number. This routine allows four decimal digits

; of score for each player.

adscr: sed ;add to score of a player

clc

adc tscr+1(y)

sta tscr+1(y)

txa

adc tscr(y)

sta tscr(y)

cld

rts

.nlist

.sbttl Tables

.list

.page

; *

; **

;********** **********************

;*********** * Relocatable Tables *

;********** **********************

; **

; *

 

 

misc: .byte 7c,46 ;misc information for initialization

;

; Frcmov is a table used for smooth movement of objects at

; fractional speeds. To use it, assume speed byte is xxxx.xxxx

; (in pixels per frame) and do the following:

; lda #0 ;init number of pixels to move to 0

; sta t0

; lda frame ;get frame number

; and #0f ;use only low nybble

; tay ;index into frcmov

; lda frcmov(y) ;get table value

; and speed ;time to let fractional speed overflow

; ;into a pixel movement?

; beq 10$ ;no, skip it

; inc t0 ;yes, t0 is now 1

;10$: lda speed ;get speed again

; lsr ;shift out fractional portion

; lsr

; lsr

; lsr

; clc ;add to overflow from fractional part

; adc t0

;

; accumulator now contains the number of pixels to move this frame.

frcmov: .byte 1,8,4,8,2,8,4,8,0,8,4,8,2,8,4,8

gf1rst: .byte 0a0,80 ;gflg1 values after game reset

gf1sel: .byte 30,10 ;gflg1 values after game select

;

; copyright notice graphics tables

col1: .byte 79,85,0b5,0a5,0b5,85,79

col2: .byte 17,15,15,77,55,55,77

col3: .byte 71,41,41,71,11,11,70

col4: .byte 49,49,49,0c9,49,49,0be

col5: .byte 55,55,55,0d9,55,55,99

.page

; *

; **

;********** *******************************

;*********** * Fixed (Page-aligned) Tables *

;********** *******************************

; **

; *

 

 

PALIGN

;

; Hmvtab contains reset counts and hmove values for objects on the

; screen. To use it, do the following (this example positions the ball):

;

; lda posn ;get horizontal position of ball

; sta wsync ;0 sync up for reset line

; tax ;2 index into hmvtab

; lda hmvtab(x) ;6 get table value

; sta hmbl ;9 set hmove value from high nybble

; and #0f ;11 keep low nybble for time loop

; tay ;13 tfr to y for loop

; nop ;15 waste 2 cycles

; dey ;17;22 etc. timing loop

; bpl .-1 ;20;25 etc.

; sta resbl ;set the ball's position right here

; sta wsync ;finish the line

; sta hmove ;execute the fine positioning hmove

;

; remember, hmvtab must not cross a page boundary, because if it does

; it could cause the instruction "lda hmvtab(x)" to take 5 cycles instead of

; 4, and that would throw off the timing of the reset line.

hmvtab: .byte 60,50,40,30,20,10,00,0f0,0e0,0d0,0c0,0b0,0a0,90

.byte 71,61,51,41,31,21,11,01,0f1,0e1,0d1,0c1,0b1,0a1,91

.byte 72,62,52,42,32,22,12,02,0f2,0e2,0d2,0c2,0b2,0a2,92

.byte 73,63,53,43,33,23,13,03,0f3,0e3,0d3,0c3,0b3,0a3,93

.byte 74,64,54,44,34,24,14,04,0f4,0e4,0d4,0c4,0b4,0a4,94

.byte 75,65,55,45,35,25,15,05,0f5,0e5,0d5,0c5,0b5,0a5,95

.byte 76,66,56,46,36,26,16,06,0f6,0e6,0d6,0c6,0b6,0a6,96

.byte 77,67,57,47,37,27,17,07,0f7,0e7,0d7,0c7,0b7,0a7,97

.byte 78,68,58,48,38,28,18,08,0f8,0e8,0d8,0c8,0b8,0a8,98

.byte 79,69,59,49,39,29,19,09,0f9,0e9,0d9,0c9

;

; End of Memory

;

.=0fffc

.word init ;start vector

.word init

.end

Link to comment
Share on other sites

Hi there!

 

; .INTSET ENABLES INTERRUPTS WHEN IN A RAM VERSION, BUT ALLOWS INTERRUPTS

; TO BE DISABLED IN THE ROMMED VERSION, BY THE USE OF THE TERM ZZZROM.

; AS LONG AS ZZZROM IS UNDEFINED, INTERRUPTS WILL BE ENABLED, AND A

; PROGRAM CAN BE HALTED BY CONTROL-C.  BEFORE ROMMING THE PROGRAM, MERELY

; INSERT A DEFINITION FOR ZZZROM, SUCH AS ZZZROM = 1.

 

:-o :-o :-o

 

Greetings,

Manuel

Link to comment
Share on other sites

Hi there!

 

Uihjah...

 

Skeleton = 4K-Template

 

Phew... and I thought this were some parts of an unfinished game... :twisted:

 

Anyway, DASM'd:

 

 

; VCS SKELETON PROGRAM
; COPYRIGHT ATARI, 1982

   PROCESSOR 6502
   INCLUDE VCS.H

; *
; **
;********** ********************
;*********** * ASSORTED EQUATES *
;********** ********************
; **
; *

GSCON   = 45;GAME SELECT TIMER INITIAL VALUE
OVRCON  = $25;OVERSCAN TIMER INITIAL VALUE
VBLCON  = $2B;VBLANK TIMER INITIAL VALUE
GMAX    = $03;HIGHEST GAME # +1

; *
; **
;********** *****************************
;*********** * VARIABLES (RAM PAGE ZERO) *
;********** *****************************
; **
; *

   SEG.U VARS
   ORG $80

TCOL    DS 1   ;TOP SCORE COLOR
BCOL    DS 1   ;BOTTOM SCORE COLOR
GFLG1   DS 1   ;GAME STATUS BITS
              ;80 1= GAME IS IN PLAY
              ;40 1= BONZO (EASY) GAME
              ;20 1= ONE-PLAYER GAME
              ;10 1= SELECT MODE
              ;08 1= COLOR-SHIFTING ATTRACT MODE
              ;04 NOT USED YET
              ;02 NOT USED YET
              ;01 NOT USED YET
GAMNO   DS 1   ;GAME NUMBER (DECIMAL)
GSTIM   DS 1   ;GAME SELECT TIMER
TSCR    DS 2   ;TOP PLAYER'S SCORE
BSCR    DS 2   ;BOTTOM PLAYER'S SCORE
RAND    DS 1   ;"RANDOM" NUMBER SEED/LAST NUMBER
RNDIND  DS 1   ;"RANDOM" NUMBER INDEX
FRAME   DS 1   ;FRAME COUNTER
HFRAM   DS 1   ;HI BYTE OF FRAME COUNTER
ATIM    DS 1   ;ATTRACT TIMER
ATMASK  DS 1   ;ATTRACT LUM MASK
T0      DS 1   ;TEMPORARY VARIABLES
T1      DS 1

;; *
;; **
;;********** ******************
;;*********** * MACROS *
;;********** ******************
;; **
;; *
;;
;; PALIGN WILL AUTOMATICALLY ALIGN FOLLOWING CODE WITH A PAGE VOUNDARY.
;; IT WILL USUALLY BE USED AT THE TOP OF TABLES, SO THAT A TABLE WON'T
;; CROSS A BOUNDARY AND FUCK UP A KERNEL.
;;
;.MACRO PALIGN
;.=<.+0FF>&0FF00
;.ENDM
;;
;;
;; .INTSET ENABLES INTERRUPTS WHEN IN A RAM VERSION, BUT ALLOWS INTERRUPTS
;; TO BE DISABLED IN THE ROMMED VERSION, BY THE USE OF THE TERM ZZZROM.
;; AS LONG AS ZZZROM IS UNDEFINED, INTERRUPTS WILL BE ENABLED, AND A
;; PROGRAM CAN BE HALTED BY CONTROL-C. BEFORE ROMMING THE PROGRAM, MERELY
;; INSERT A DEFINITION FOR ZZZROM, SUCH AS ZZZROM = 1.
;;
;.MACRO .INTSET
;.IF NDF,ZZZROM
;CLI
;.IFF
;SEI
;.ENDC
;.ENDM
;;
;;
;; LINE WILL DECREMENT THE LINE COUNT, IF REQUESTED, WILL SET UP A
;; PLAYER, IF REQUESTED, AND WILL SET UP A MISSILE OR BALL DURING A
;; KERNEL LINE. THE LINE COUNT MAY BE DECREMENTED BY ANY VALUE, SET
;; AS ARGUMENT A1. IF A1 IS ZERO, THAT PART OF THE CODE IS NOT
;; ASSEMBLED. ARGUMENT A2 SPECIFIES THE VERTICAL POSITION OF THE
;; PLAYER, BY NAME OF RAM POSITION WHERE THAT VALUE IS LOCATED. IF
;; THAT ARGUMENT IS SET TO ZERO, THE CODE FOR HANDLING THE PLAYER
;; IS LEFT OUT.
;;
;; THERE ARE EIGHT ARGUMENTS, BUT A8 MUST NOT BE SPECIFIED WHEN
;; INVOKING THE MACRO. IT IS A DUMMY FOR CREATING A JUMP ADDRESS.
;; THE OTHERS MUST BE USED, AT LEAST TO THE POINT OF PUTTING IN A
;; COMMA AS A PLACE-HOLDER. THE ARGUMENTS AND THEIR MEANINGS ARE:
;;
;; A1 LINE COUNT DECREMENT AMOUNT (USUALLY 1 OR 2; IF 0, CODE IS
;; SKIPPED)
;; A2 NAME OF RAM LOCATION FOR VERT. POSITION OF A PLAYER. IF 0,
;; CODE FOR PLAYER SETUP IS LEFT OUT
;; A3 PLAYER'S HEIGHT
;; A4 NAME OF PLAYER'S GRAPHICS TABLE
;; A5 NAME OF A TEMPORARY STORAGE LOCATION FOR THAT PLAYER'S GRAPHICS
;; A6 NAME OF LOCATION FOR MISSILE'S OR BALL'S VERTICAL POSITION
;; A7 HEIGHT OF MISSILE OR BALL
;; A8 DUMMY JUMP ADDRESS -- DON'T PUT A VALUE IN FOR THIS ARGUMENT!!!
;;
;; AN EXAMPLE FOR THE FIRST LINE OF A DOUBLE-LINE KERNEL MIGHT BE:
;;
;; LINE 2,VP0,8,P0TAB,GP0,VM0,14.
;;
;; THE SECOND LINE OF THE KERNEL MIGHT LOOK LIKE:
;;
;; LINE 0,VP1,10.,P1TAB,GP1,VBL,4
;;
;; A LINE WITH NO PLAYER MIGHT BE CALLED AS FOLLOWS:
;;
;; LINE 1,0,,,,VM1,6
;;
;; NOTE THAT ALL NUMERIC VALUES ARE IN HEX, AND DECIMAL VALUES MUST END
;; WITH A DOT. THIS MACRO USES THE ACCUMULATOR AND Y REGISTER, BUT LEAVES
;; THE X REGISTER FREE.
;;
;; THE RESULTS OF THIS MACRO MUST BE INVOKED AT THE START OF THE NEXT LINE,
;; PROBABLY IMMEDIATELY AFTER AT STA WSYNC, OR AFTER STA WSYNC, STA HMOVE.
;; IF THE PLAYER GRAPHICS HAS BEEN STORED IN GP1, FOR INSTANCE, AND YOU
;; ARE ABOUT TO PUT UP THAT PLAYER AND THE BALL, AS IN THE SECOND EXAMPLE
;; ABOVE, YOU WOULD PUT IN CODE:
;; STY ENABL
;; LDY GP1
;; STY GRP1
;; AND THEN CONTINUE WITH REST OF CODE FOR THAT LINE. THERE SHOULD BE
;; ENOUGH TIME TO GET A PLAYFIELD STARTED, BUT DON'T DECREMENT LINE
;; COUNTS WHERE THERE WILL BE NEW PLAYFIELD. THERE ISN'T ENOUGH TIME.
;; PUT A 0 IN A1 FOR THOSE LINES, IN A TWO-LINE KERNEL, AND PUT A 2 IN
;; A1 ON THE NEXT LINE, WHERE THERE WILL BE MORE TIME.
;;
;; THE ROUTINE WALKS DOWN THROUGH THE PLAYER GRAPHICS TABLE AS IT MOVES
;; DOWN THE SCREEN, SO THE FIRST VALUE OF THE TABLE SHOULD BE 0, TO SET
;; THAT VALUE INTO THE GRAPHICS STORE LOCATION WHEN THE PLAYER ISN'T TO
;; APPEAR.
;;
;.MACRO LINE A1,A2,A3,A4,A5,A6,A7,?A8
;.IF NE,A2
;LDA A2
;SEC
;SBC LNCNT
;CMP #A3
;BCS A8
;TAY
;LDA A4(Y)
;STA A5
;.ENDC
;A8: LDY #0
;LDA LNCNT
;SEC
;.IF NE,A1
;SBC #A1
;STA LNCNT
;.ENDC
;SBC A6
;CMP #-A7
;BCC .+4
;LDY #2
;.ENDM
;;

; *
; **
;********** ******************
;*********** * INITIALIZATION *
;********** ******************
; **
; *


   SEG Bank0
   ORG $F000
START
   SEI;DISABLE INTERRUPTS
   CLD;BINARY ARITHMETIC
   LDX #0
   TXA
   STA SWACNT;SET PORTA FOR INPUT
10$: STA 0,X;CLEAR HARDWARE REGISTERS AND RAM
   INX
   BNE 10$
   DEX;FF
   STX GFLG1;SET SELECT MODE FLAG
   TXS;INIT STACK PTR
;
; PERFORM A GAME SELECT, GAME # 1
;
   JSR INITSL;SIMULATE SELECT LEVER PRESS
;
; END OF INITIALIZATION
;
   JMP OVERSC;GO START WITH OVERSCAN

; *
; **
;********** ****************
;*********** * VIDEO KERNEL *
;********** ****************
; **
; *


KERNEL: STA WSYNC;0
   LDA #$82;2 LOAD BACKGROUND COLOR
   EOR ATIM;5 COMP FOR ATTRACT MODE
   AND #$F7;7
   STA COLUBK;10
   LDX #180;12 LOAD NUMBER OF LINES
10$: STA WSYNC;0 FINISH THE LINE
   DEX;2 DONE?
   BNE 10$;4,5 NO, GO
   LDA GFLG1;7 ARE WE IN SELECT MODE?
   AND #$10;9
   BNE COPY;11,12 YES, GO DO COPYRIGHT NOTICE
   LDX #$11;13 LOAD NUMBER OF LINES
20$: STA WSYNC;0 END THE LINE
   DEX;2 DONE?
   BNE 20$;4,5 NO, GO
   JMP OVERSC;7 YES, EXIT
;
; DISPLAY COPYRIGHT NOTICE
;
COPY: STA WSYNC;0 SYNC UP
   STX PF0;3 CLEAR PLAYFIELD REGS
   STX PF1;6
   STX PF2;9
   NOP;11 WASTE SOME CYCLES
   STA T0;14 WASTE SOME MORE
   LDA BCOL;17 SET UP PLAYER COLOR
   EOR ATIM;20 ADJUST FOR ATTRACT COLORS
   AND ATMASK;23 ENSURE LOW LUM IF ATTRACT COLORS
   STA COLUP0;26
   STA COLUP1;29
   NOP;31 WASTE 2 CYCLES HERE
   LDA #$F0;33 SET UP FINE POSITIONING IN ADVANCE
   STA HMP0;36
   LDX #0;38
   STX HMP1;41
   STA RESP0;44 RESET PLAYER ZERO...
   STA RESP1;47 ...AND PLAYER ONE
   STA WSYNC;0
   STA HMOVE;3 EXECUTE FINE ADJUSTMENT
   LDA #$CB;5 SET NUSIZ FOR SMALL PLAYERS
   STA NUSIZ0;8 AND PROPER NUMBER OF COPIES
   LDX #1;10
   STX NUSIZ1;13
; DO DISPLAY
   LDX #$07;15 FOR 8 LINES OF THE SCREEN...
1$: STX T1;18,66 SAVE INDEX BECAUSE X IS USED LATER
   STA WSYNC;0
   LDY #2;2 TIME OUT TO CENTER OF SCREEN
   DEY;4;9
   BNE .-1;7;11
   STA T0;14 WASTE 3 CYCLES TO GET TIMING RIGHT
   LDA COL1-1,X;18 GET GRAPHICS FOR FIRST STORE
   STA GRP0;21 STORE IT
   LDA COL2-1,X;25 SAME FOR P1
   STA GRP1;28
   LDY COL3-1,X;32 NOW GET TRICKY TO SAVE TIME...
   LDA COL4-1,X;36 USE X AND Y AND A TO THEIR FULLEST
   STA T0;39 USE TEMP 0 ALSO FOR TIME SAVINGS
   LDA COL5-1,X;43 NOW LOAD UP ALL 3 REGS
   LDX T0;46
   STY GRP0;49 AND STORE 'EM AS FAST AS POSSIBLE
   STX GRP1;52 (TIMING IS VERY CRUCIAL HERE)
   STA GRP0;55
   LDX T1;58 NOW RESTORE INDEX
   DEX;60
   BNE 1$;62,63 AND BRANCH BACK TILL DONE
   STX GRP0;65 CLEAR PLAYER GRAPHICS FOR NEATNESS
   STX GRP1;68
   STA WSYNC;0 DISPLAY TWO BLANK LINES
   STA WSYNC;0 (BOTTOM MARGIN)
   JMP OVERSC
;
; END OF KERNEL
;

; *
; **
;********** ***************************
;*********** * OVERSCAN: 30 SCAN LINES *
;********** ***************************
; **
; *


;
; TIE UP SCREEN LOOSE ENDS
;
OVERSC: LDX #0
   STX COLUBK;TURN OFF BACKGROUND
   LDA #OVRCON;SET UP OVERSCAN TIMER
   STA TIM64T
   LDA #$82;TURN ON VBLANK, GROUND THE POTS
   STA VBLANK
;
; UPDATE FRAME COUNTER
;
   INC FRAME
   BNE 10$;GO IF NO OVERFLOW
   INC HFRAM
   LDA #$30;TIME TO GO INTO ATTRACT?
   CMP HFRAM
   BNE 10$;NO, GO
   LDA GFLG1;YES, SET THE FLAG
   ORA #$08
   STA GFLG1
10$:
;
; CHECK FOR RESET/GAME SELECT
;
   JSR GSRST;CHECK LEVERS...
   BCS 99$;IF LEVER WAS PRESSED...
   JMP INTST;SKIP GAME PLAY THIS FRAME
99$:
;
;
;********************************************
; PUT OVERSCAN CALCS HERE *
;********************************************
;
;
;
; END OF OVERSCAN
;
INTST:
   LDX INTIM;OVERSCAN DONE YET?
   BNE INTST;NO, GO BACK
VSNC: LDX #$02;YES, DO VSYNC
   STX VSYNC
   STA WSYNC;SEND 4 LINES OF VSYNC
   STA WSYNC
   STA WSYNC
   STA WSYNC
   LDA #0
   STA VSYNC;TURN OFF VSYNC (A=0)

; *
; **
;********** *************************
;*********** * VBLANK: 37 SCAN LINES *
;********** *************************
; **
; *


;
; START VBLANK TIMER
;
VBLNK: LDA #VBLCON;SET UP VBLANK TIMER
   STA TIM64T
;
;
;********************************************
; PUT VBLANK CALCS HERE *
;********************************************
;
;
; COLOR-SHIFT ATTRACT MODE
;
SHFT: LDY #$FF;ASSUME NO ATTRACT MASK
   LDA GFLG1;ARE WE IN COLOR ATTRACT?
   AND #$08
   BNE 5$;YES, GO
   STA ATIM;NO, RESET ATTRACT SHIFT KEY TO ZERO
   BEQ 99$;ALWAYS TAKEN
5$: LDY #$F7;LOAD ATTRACT MASK
   LDA FRAME;IS IT TIME TO SHIFT?
   BNE 99$;NO, GO
   INC ATIM;SET NEW COLOR-SHIFT MASK
99$: STY ATMASK;STORE CURRENT LUM MASK
;
; END OF VBLANK
;
INTST2:
   LDA INTIM;DONE WITH VBLANK YET?
   BNE INTST2;NO, GO BACK
   STA WSYNC;YES, GET READY FOR KERNEL
   STA VBLANK;TURN OFF VBLANK, AND START CHARGING POTS
   STA HMCLR;RESET HORIZ. MOTION REGS TO 0
   STA CXCLR;CLEAR COLLISIONS
   JMP KERNEL;GO FOR IT

; *
; **
;********** ******************************
;*********** * GAME SELECT AND GAME RESET *
;********** ******************************
; **
; *


; CHECK TO SEE IF GAME SELECT OR GAME RESET LEVERS ARE BEING
; PRESSED. IF YES, THEN CHECK TO SEE IF TIME-OUT HAS OCCURRED. IF
; YES, THEN EXECUTE THE FUNCTION. OTHERWISE RETURN WITH CARRY SET,
; INDICATING THAT NO ACTION WAS TAKEN. IF GAME SELECT OR RESET DID
; TAKE PLACE, RETURN WITH CARRY CLEAR, SO THAT THE OVERSCAN CALCS WILL
; BE SKIPPED (RESET OR SELECT USUALLY TAKES A LONG TIME TO DO).
GSRST: LDA SWCHB;READ CONSOLE SWITCHES
   ROR
   BCC GRS;GO IF RESET LEVER PRESSED
GS2: ROR
   BCC GSEL;GO IF GAME SELECT LEVER PRESSED
   LDX #1
   STX GSTIM
GSEX: SEC
   RTS;RTS WITH CARRY SET MEANS NO ACTION
;
; GAME SELECT
GSEL: DEC GSTIM;TIME TO EXECUTE?
   BNE GSEX;NO, GO
INITSL: LDA #$2D;RESET TIMER
   STA GSTIM
   LDA GFLG1;ARE WE IN SELECT MODE?
   AND #$10
   BEQ 12$;NO, DON'T INC GAME NUMBER
   SED;NEW GAME NUMBER
   LDA GAMNO
   CLC
   ADC #1;ADD 1 TO OLD NUMBER
   CMP #GMAX;TOO HIGH?
   BNE 10$;NO, SKIP RESET
   LDA #1;YES, RESET TO 1
10$: STA GAMNO
   CLD;RESTORE BINARY FUNCTIONING
;***************************************
; PUT GAME SELECT LOGIC HERE *
;***************************************
12$: LDX GAMNO;SET GFLG1 FROM TABLE
   LDA GF1SEL-1,X
   STA GFLG1
   BNE GSRS;ALWAYS TAKEN
;
; GAME RESET
GRS: DEC GSTIM;TIME TO EXECUTE?
   BNE GSEX;NO, EXIT
   LDX #$10;RESET TIMER
   STX GSTIM
   LDX GAMNO;SET GFLG1 FROM TABLE
   LDA GF1RST-1,X
   STA GFLG1
;**************************************
; PUT GAME RESET LOGIC HERE *
;**************************************
   LDX #0;RESET SCORES
   STX TSCR
   STX TSCR+1
   STX BSCR
   STX BSCR+1
;
; BOTH FUNCTIONS
GSRS: LDA #$05;SET UP HARDWARE
   STA NUSIZ0
   STA NUSIZ1
   LDA #$21
   STA CTRLPF
   LDA #4
   STA AUDC0
   STA CXCLR
   LDA #0
   STA HFRAM;TURN OFF COLOR ATTRACT
   LDX #1;SET UP SCREEN COLORS
20$: LDA MISC,X
   STA TCOL,X
   DEX
   BPL 20$
99$: CLC;RETURN WITH CLEAR CARRY
   RTS

; *
; **
;********** ************************
;*********** * ASSORTED SUBROUTINES *
;********** ************************
; **
; *


;
; "RANDOM" NUMBER ROUTINE
;
; RETURNS A "RANDOM" NUMBER IN THE ACCUMULATOR. IF IT DOESN'T
; SEEM VERY RANDOM TRY PLAYING AROUND WITH THE BASE ADDRESS OF THE FIRST
; TWO EXCLUSIVE OR'S... FIND VERY VARIED PIECES OF YOUR PROGRAM TO USE,
; AND IT SHOULD RETURN VERY UNPREDICTABLE RESULTS. ANOTHER TRICK IS TO
; SOMEHOW DO AN EOR WITH YOUR GAME CONTROLLERS... THIS IS ABOUT
; AS RANDOM AS DATA CAN GET, AND USUALLY MAKES A DIFFERENCE.
RNDNO: LDA RAND;GET SEED (LAST NUMBER)
   LDX RNDIND;AND INDEX
   EOR OVERSC,X;"RANDOMIZE"
   EOR KERNEL,X
   ASL;ROTATE TO AVOID SINGLE-BIT
   ADC #0;STATE PREFERENCES
   INX
   STX RNDIND;SAVE NEW INDEX
   EOR HFRAM;AND USE FRAME COUNTER FOR
   EOR FRAME;LONG REPEAT TIME
   STA RAND;SAVE NEW SEED
   RTS;EXIT
;
; SCORE ADDITION ROUTINE
;
; ADDS VALUE FOUND IN ACCUMULATOR TO THE PLAYER WHOSE OFFSET IS IN
; Y-REG. KEEP IN MIND THAT PLAYER ZERO SHOULD BE Y-REG = 0 AND PLAYER
; ONE SHOULD BE Y-REG = 2. ALSO, REMEMBER THE AMOUNT TO ADD (IN THE ACC.)
; SHOULD BE A DECIMAL NUMBER. THIS ROUTINE ALLOWS FOUR DECIMAL DIGITS
; OF SCORE FOR EACH PLAYER.
ADSCR: SED;ADD TO SCORE OF A PLAYER
   CLC
   ADC TSCR+1,Y
   STA TSCR+1,Y
   TXA
   ADC TSCR,Y
   STA TSCR,Y
   CLD
   RTS

; *
; **
;********** **********************
;*********** * RELOCATABLE TABLES *
;********** **********************
; **
; *


MISC: .BYTE $7C,$46;MISC INFORMATION FOR INITIALIZATION
;
; FRCMOV IS A TABLE USED FOR SMOOTH MOVEMENT OF OBJECTS AT
; FRACTIONAL SPEEDS. TO USE IT, ASSUME SPEED BYTE IS XXXX.XXXX
; (IN PIXELS PER FRAME) AND DO THE FOLLOWING:
; LDA #0;INIT NUMBER OF PIXELS TO MOVE TO 0
; STA T0
; LDA FRAME;GET FRAME NUMBER
; AND #$0F;USE ONLY LOW NYBBLE
; TAY;INDEX INTO FRCMOV
; LDA FRCMOV,Y;GET TABLE VALUE
; AND SPEED;TIME TO LET FRACTIONAL SPEED OVERFLOW
;;INTO A PIXEL MOVEMENT?
; BEQ 10$;NO, SKIP IT
; INC T0;YES, T0 IS NOW 1
;10$: LDA SPEED;GET SPEED AGAIN
; LSR;SHIFT OUT FRACTIONAL PORTION
; LSR
; LSR
; LSR
; CLC;ADD TO OVERFLOW FROM FRACTIONAL PART
; ADC T0
;
; ACCUMULATOR NOW CONTAINS THE NUMBER OF PIXELS TO MOVE THIS FRAME.
FRCMOV: .BYTE 1,8,4,8,2,8,4,8,0,8,4,8,2,8,4,8
GF1RST: .BYTE $A0,$80;GFLG1 VALUES AFTER GAME RESET
GF1SEL: .BYTE $30,$10;GFLG1 VALUES AFTER GAME SELECT
;
; COPYRIGHT NOTICE GRAPHICS TABLES
COL1: .BYTE $79,$85,$B5,$A5,$B5,$85,$79
COL2: .BYTE $17,$15,$15,$77,$55,$55,$77
COL3: .BYTE $71,$41,$41,$71,$11,$11,$70
COL4: .BYTE $49,$49,$49,$C9,$49,$49,$BE
COL5: .BYTE $55,$55,$55,$D9,$55,$55,$99

; *
; **
;********** *******************************
;*********** * FIXED (PAGE-ALIGNED) TABLES *
;********** *******************************
; **
; *

   ALIGN 256

;
; HMVTAB CONTAINS RESET COUNTS AND HMOVE VALUES FOR OBJECTS ON THE
; SCREEN. TO USE IT, DO THE FOLLOWING (THIS EXAMPLE POSITIONS THE BALL):
;
; LDA POSN;GET HORIZONTAL POSITION OF BALL
; STA WSYNC;0 SYNC UP FOR RESET LINE
; TAX;2 INDEX INTO HMVTAB
; LDA HMVTAB,X;6 GET TABLE VALUE
; STA HMBL;9 SET HMOVE VALUE FROM HIGH NYBBLE
; AND #$0F;11 KEEP LOW NYBBLE FOR TIME LOOP
; TAY;13 TFR TO Y FOR LOOP
; NOP;15 WASTE 2 CYCLES
; DEY;17;22 ETC. TIMING LOOP
; BPL .-1;20;25 ETC.
; STA RESBL;SET THE BALL'S POSITION RIGHT HERE
; STA WSYNC;FINISH THE LINE
; STA HMOVE;EXECUTE THE FINE POSITIONING HMOVE
;
; REMEMBER, HMVTAB MUST NOT CROSS A PAGE BOUNDARY, BECAUSE IF IT DOES
; IT COULD CAUSE THE INSTRUCTION "LDA HMVTAB,X" TO TAKE 5 CYCLES INSTEAD OF
; 4, AND THAT WOULD THROW OFF THE TIMING OF THE RESET LINE.
HMVTAB:
   .BYTE $60,$50,$40,$30,$20,$10,$00,$F0,$E0,$D0,$C0,$B0,$A0,$90
   .BYTE $71,$61,$51,$41,$31,$21,$11,$01,$F1,$E1,$D1,$C1,$B1,$A1,91
   .BYTE $72,$62,$52,$42,$32,$22,$12,$02,$F2,$E2,$D2,$C2,$B2,$A2,92
   .BYTE $73,$63,$53,$43,$33,$23,$13,$03,$F3,$E3,$D3,$C3,$B3,$A3,93
   .BYTE $74,$64,$54,$44,$34,$24,$14,$04,$F4,$E4,$D4,$C4,$B4,$A4,94
   .BYTE $75,$65,$55,$45,$35,$25,$15,$05,$F5,$E5,$D5,$C5,$B5,$A5,95
   .BYTE $76,$66,$56,$46,$36,$26,$16,$06,$F6,$E6,$D6,$C6,$B6,$A6,96
   .BYTE $77,$67,$57,$47,$37,$27,$17,$07,$F7,$E7,$D7,$C7,$B7,$A7,97
   .BYTE $78,$68,$58,$48,$38,$28,$18,$08,$F8,$E8,$D8,$C8,$B8,$A8,98
   .BYTE $79,$69,$59,$49,$39,$29,$19,$09,$F9,$E9,$D9,$C9

;
; END OF MEMORY
;
   ORG $FFFC
   .WORD START
   .WORD START

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...