451 lines
8.6 KiB
NASM
451 lines
8.6 KiB
NASM
B>type init.asm
|
|
|
|
.title "INTERRUPT ROUTINE"
|
|
.sbttl "FRENZY"
|
|
.ident INT
|
|
;--------------------
|
|
; interrupt routine
|
|
;--------------------
|
|
.insert equs
|
|
.intern INT,PLOT
|
|
.extern RtoA
|
|
;---------------------------------------
|
|
; this routine does writing, erasing,
|
|
; moving, and pattern animation based
|
|
; on the following structure
|
|
; ---- v.stat vector status <- IY points here
|
|
; ---- setup last magic value
|
|
; -------- o.a.l/h old screen address
|
|
; -------- o.p.l/h last pattern addr.
|
|
; ---- tprime value to stuff into time
|
|
; ---- time time til move
|
|
; ---- v.x x velocity
|
|
; ---- v.y y velocity
|
|
; ---- p.x x position
|
|
; ---- p.y y position
|
|
; -------- d.p.l/h pattern pointer
|
|
;--------------------------------------
|
|
INT: out NMIOFF ;turn off nmi's
|
|
di ;believe it [cuz of calls]
|
|
push psw
|
|
in WHATI ;bottom of screen?
|
|
rar ;test bit 0
|
|
jrc BS ;skip if middle of screen
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
; Middle of Screen Interrupt
|
|
;_______________________________
|
|
; use only AF,BC,HL
|
|
out NMION ;prob get nmi immed'ly
|
|
push h ;save em
|
|
push b
|
|
lxi h,SWD ; check coins
|
|
mov a,m ;oldset switch
|
|
inx h
|
|
mov b,m ;old sw.
|
|
xra b ;difference in a
|
|
mov c,a ; in c
|
|
in I.O2 ;new sw.s
|
|
cma
|
|
mov m,a ;store new switch
|
|
dcx h
|
|
mov m,b ;make old->oldest
|
|
ana c ;check new=1 old=1 oldest=0
|
|
ani 0c0H
|
|
..lp: dcx h ;->cackle
|
|
bit 7,a ; check bit
|
|
jrz ..sk
|
|
inr m ;inc coin counter
|
|
..sk: add a ;shift bits
|
|
jrnz ..lp
|
|
; update man alternator
|
|
lxi h,Man.Alt
|
|
srlr m
|
|
;take care of seconds counter
|
|
lxi h,T60cnt
|
|
dcr m
|
|
jp ..ous
|
|
mvi m,60 ;reset seconds timer
|
|
mvi c,8 ;inc total seconds in backgnd
|
|
call ItemInc# ;pushes all reg used
|
|
lda DEMO
|
|
ora a
|
|
mvi c,7 ;total game time
|
|
cz ItemInc
|
|
lxi h,KWait ;adjust kill off
|
|
mov a,m
|
|
ora a
|
|
jrz ..ous
|
|
dcr a
|
|
mov m,a
|
|
..ous: call GetC# ;if no credits
|
|
mvi L,0
|
|
ora a ;skip to waiter
|
|
jrz I.but
|
|
cpi 1 ;if only one credit
|
|
mvi L,1 ;then check only button1
|
|
jrz I.but
|
|
mvi L,3
|
|
I.but: in I.O2 ;check start button[s]
|
|
cma
|
|
ana l
|
|
mov l,a ;save buttons
|
|
lda StartB ;previous buttons
|
|
ora l
|
|
sta StartB ;save for main
|
|
jz ..exit
|
|
bit 7,a ;in play flag
|
|
jz GO# ;go play NOW
|
|
..exit: pop b
|
|
pop h
|
|
jmp BYE
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
; Bottom of Screen Interrupt
|
|
;_______________________________
|
|
BS: push y ;save old jobs
|
|
push x
|
|
push h
|
|
push d
|
|
push b
|
|
exaf
|
|
push psw
|
|
;< do color man every 4 int?>
|
|
lxi h,0 ;null vector pointer
|
|
shld OLD1
|
|
shld OLD2
|
|
shld OLD3
|
|
lxi h,Inttyp ;test alternator
|
|
rlcr m ;by rotating the bits
|
|
mvi b,3 ;do 2 others if no man
|
|
lhld L.PTR ;robot list pointer
|
|
jc ..ilp
|
|
lxi h,Vectors
|
|
shld Old3 ;save for updates
|
|
call SECT1 ;rewrite man
|
|
call UNCMAN# ;uncolor man
|
|
lxi h,Vectors
|
|
bit COLOR,m ;do color
|
|
cnz COLMAN#
|
|
lhld L.PTR ;robot list pointer
|
|
mvi b,2 ;# of robots to do
|
|
..ilp: push b
|
|
call SECT1 ;rewrite robot
|
|
pop b
|
|
lhld V.PTR ;Get vector pointer
|
|
; save pointer for later update
|
|
xchg
|
|
mov a,b ;get index
|
|
add a ;double
|
|
lxi h,Old1-2 ;save array start
|
|
add l ;add b*2 to hl
|
|
mov l,a
|
|
mov a,h
|
|
aci 0
|
|
mov h,a
|
|
mov m,e ;store vector address
|
|
inx h ;for later update
|
|
mov m,d
|
|
xchg
|
|
..inc: lxi d,VLEN ;delta to next vector
|
|
dad d ;point to next
|
|
lxi d,Vectors+(MaxVec*VLEN) ;end of list
|
|
mov a,l ;see if at end
|
|
cmp e
|
|
jnz ..tst
|
|
mov a,h
|
|
cmp d
|
|
jz ..end
|
|
..tst: mov a,m ;see if vector is on
|
|
ani (1<INUSE)
|
|
jrz ..inc ;if not look at another
|
|
djnz ..ilp
|
|
jmp ..done
|
|
..end: lxi h,Vectors+VLEN ;first non-man vector
|
|
..done: shld L.PTR ;next one to look at
|
|
call BUL.V# ;rewrite & vector bolts
|
|
; now that bolts have done hitting things
|
|
; update Vectors (coordinates)
|
|
lhld OLD3 ;first vector written
|
|
call SECT3
|
|
lhld OLD2
|
|
call SECT3
|
|
lhld OLD1 ;last vector written
|
|
call SECT3 ;update animation and vector
|
|
call TIMERS ;do job timers
|
|
pop psw ;restore all registers
|
|
exaf
|
|
pop b
|
|
pop d
|
|
pop h
|
|
pop x
|
|
pop y
|
|
BYE: mvi A,1 ;turn on interrupts
|
|
out I.ENAB
|
|
out NMION ;prob get nmi immed'ly
|
|
mvi A,ITAB/256
|
|
stai
|
|
im2
|
|
pop psw
|
|
ei
|
|
ret
|
|
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
; all below assume iy -> vector
|
|
; and [v.ptr]=iy
|
|
;----------------
|
|
; erase pattern
|
|
;________________
|
|
SECT1: shld V.PTR
|
|
liyd V.PTR
|
|
bit ERASE,M ;hl->v.stat
|
|
jz SECT2
|
|
res ERASE,M ;never erase more than once
|
|
inx h ;->setup
|
|
mov a,m ;get old magic value
|
|
out MAGIC
|
|
inx h ;->old address
|
|
mov e,m
|
|
inx h ;->o.a.h
|
|
mov d,m
|
|
inx h ;->old pattern
|
|
mov a,m ;hl:=[hl]
|
|
inx h ;->o.a.h
|
|
mov h,m
|
|
mov l,a
|
|
call PLOT ;xor write
|
|
lhld V.PTR
|
|
;----------------
|
|
; write pattern
|
|
;----------------
|
|
SECT2: bit WRITE,M ;check if should write
|
|
rz
|
|
res WRITE,M ;never write twice either
|
|
lxi d,P.X
|
|
dad d ;->p.x
|
|
mov e,m ;x position
|
|
inx h ;->v.y
|
|
inx h ;->p.y
|
|
mov d,m ;y position
|
|
inx h
|
|
mvi B,90H ;xor write
|
|
xchg
|
|
call RtoA
|
|
mov SETUP(y),A ;save magic
|
|
; get pattern address := @pattern.pointer
|
|
xchg
|
|
mov a,m ;->d.p.l
|
|
inx h
|
|
mov h,m ;->d.p.h
|
|
mov l,a
|
|
mov a,m ;get word in table
|
|
inx h ;which ->pattern
|
|
mov h,m
|
|
mov l,a
|
|
; check for offset pattern
|
|
inx h ;->y
|
|
mov a,m
|
|
dcx h
|
|
bit 7,A
|
|
jrz ..noo ;normal non offset
|
|
ani 7FH
|
|
mov b,a
|
|
mov c,m
|
|
inx h
|
|
inx h
|
|
xchg
|
|
lda FLIP
|
|
ora a
|
|
jz ..down
|
|
dsbc b
|
|
.byte (3eh) ;mvi a,(dad b)
|
|
..down: dad b
|
|
xchg
|
|
; store pattern away
|
|
..noo: mov O.P.L(y),L
|
|
mov O.P.H(y),H
|
|
mov O.A.L(y),E ;save screen address
|
|
mov O.A.H(y),D
|
|
call PLOT
|
|
lhld V.PTR
|
|
; check intercept
|
|
in WHATI
|
|
bit 7,A ;nz means 1 writtn over 1
|
|
rz
|
|
set INEPT,M ;set intercept bit
|
|
ret ;no point in moving object
|
|
;--------------------------
|
|
; move position, animate
|
|
;--------------------------
|
|
SECT3: shld V.PTR
|
|
; bit Color,m
|
|
; cnz COLMAN#
|
|
bit MOVE,M ;should be moved?
|
|
rz
|
|
push h
|
|
pop y ;iy->vector
|
|
; MOVE bit reset by routine that set it
|
|
lxi d,TPRIME
|
|
dad d ;->tprime
|
|
mov a,m
|
|
inx h ;->time
|
|
dcr m ;dec time,if0 then
|
|
rnz
|
|
mov m,a ;time:=tprime
|
|
; vector in x
|
|
inx h ;->V.X
|
|
mov a,m
|
|
inx h ;->p.x
|
|
add M
|
|
mov m,a
|
|
;vector y
|
|
inx h ;->v.y
|
|
mov a,m
|
|
inx h ;->p.y
|
|
add M
|
|
mov m,a
|
|
; update pattern [animate]
|
|
inx h ;->d.p.l
|
|
mov e,m
|
|
inx h ;->d.p.h
|
|
mov d,m ;get table address
|
|
inx d
|
|
inx d ;point to next entry
|
|
xchg
|
|
mov a,m ;if0 then
|
|
inx h
|
|
ora m ;jump
|
|
jnz ..sk
|
|
inx h ;get pointer
|
|
mov a,m ; to value of next word
|
|
inx h
|
|
mov h,m
|
|
mov l,a ;->head of table
|
|
.byte (3eh) ;mvi a,dcx h (7 T not 12)
|
|
..sk: dcx h
|
|
xchg ;de=table address
|
|
mov m,d ;hl->d.p.h
|
|
dcx h
|
|
mov m,e ;->d.p.l
|
|
mvi A,(1<Write)!(1<Erase)
|
|
lhld V.Ptr
|
|
ora M ;or with V.STAT
|
|
mov M,A
|
|
ret
|
|
;-----------------------
|
|
; decrement job timers
|
|
;-----------------------
|
|
TIMERS: lxi h,Timer0
|
|
mvi b,24
|
|
..loop: mov a,m
|
|
ora a
|
|
jrz ..dl
|
|
dcr m
|
|
..dl: inx h
|
|
djnz ..loop
|
|
ret
|
|
;-------------------------------
|
|
; write pattern with intercept
|
|
; 2 byte wide routine
|
|
;-------------------------------
|
|
;hl->pattern de->screen data
|
|
PLOT: mvi B,0 ; bc=pattern x size
|
|
mov a,m
|
|
inx h
|
|
dcr a
|
|
jz X1PLOT ;if not 1 then 2 bytes only!
|
|
lda FLIP
|
|
ora a ;check flip state
|
|
mov a,m ; y size
|
|
inx h
|
|
jnz XF2PLT
|
|
lxi b,Hsize-2
|
|
xchg ;de->pattern byte
|
|
Y.LOOP: exaf ;save y size
|
|
ldax d ;get pattern byte
|
|
inx d ;->next pattern byte
|
|
mov m,a ;write to screen
|
|
inx h
|
|
ldax d ;repeat for next byte
|
|
inx d
|
|
mov m,a
|
|
inx h
|
|
mov m,b ;flush shifter(b=0)
|
|
exaf
|
|
dad b ;hl->next line of screen
|
|
dcr a ;--y.size
|
|
jnz Y.LOOP
|
|
ret
|
|
;-----------------------------------------
|
|
; two byte wide upside-down plot routine
|
|
;-----------------------------------------
|
|
XF2PLT: lxi b,2-Hsize
|
|
xchg ;de->pattern byte
|
|
Y.Lp: exaf ;save y size
|
|
ldax d ;get pattern byte
|
|
inx d ;->next pattern byte
|
|
mov m,a ;write to screen
|
|
dcx h
|
|
ldax d ;repeat for next byte
|
|
inx d
|
|
mov m,a
|
|
dcx h
|
|
mvi M,0 ;flush shifter(b=0)
|
|
exaf
|
|
dad b ;hl->next line of screen
|
|
dcr a ;--y.size
|
|
jnz Y.Lp
|
|
ret
|
|
;-----------------------------
|
|
; one byte wide plot routine
|
|
;-----------------------------
|
|
;hl->pattern de->screen data
|
|
X1PLOT: lda FLIP ;hl->y size
|
|
ora a ;check flip state
|
|
mov a,m ;load y size
|
|
inx h ;->first data byte
|
|
jnz XF1PLT
|
|
lxi b,Hsize-1
|
|
xchg ;de->pattern byte
|
|
..loop: exaf ;save y size
|
|
ldax d ;get pattern byte
|
|
inx d ;->next pattern byte
|
|
mov m,a ;write to screen
|
|
inx h
|
|
mov m,b ;flush shifter(b=0)
|
|
exaf
|
|
dad b ;hl->next line of screen
|
|
dcr a ;--y.size
|
|
jnz ..loop
|
|
ret
|
|
;-----------------------------------
|
|
; flipped 1 byte wide plot routine
|
|
;-----------------------------------
|
|
XF1PLT: lxi b,1-Hsize
|
|
xchg ;de->pattern byte
|
|
..loop: exaf ;save y size
|
|
ldax d ;get pattern byte
|
|
inx d ;->next pattern byte
|
|
mov m,a ;write to screen
|
|
dcx h ;backwards writing
|
|
mvi M,0 ;flush shifter(b=0)
|
|
exaf
|
|
dad b ;hl->next line of screen
|
|
dcr a ;--y.size
|
|
jnz ..loop
|
|
ret
|
|
BYTE2:: .byte 0
|
|
;------------------
|
|
; interrupt table
|
|
;------------------
|
|
.loc 3FFCH
|
|
|
|
ITAB: .word INT ;video
|
|
BYTE4:: .word 0 ;xsum
|
|
|
|
.loc 4000h
|
|
.word BYTE1#
|
|
.word BYTE2
|
|
.word BYTE3#
|
|
.word BYTE4
|
|
.word BYTE5#
|
|
|
|
.end
|