A86: help with game
[Prev][Next][Index][Thread]
A86: help with game
I am having trouble with this program. I know that it may seem very large to
look at but I think that it may be easier to find the problem if you copy and
paste it and use it with your emulator. That way you have an idea of where it
messes up. It is a program that has a little man go left or right on the
screen. It just draws lines but it will do something when you push either
right or left. The escape button works so don't worry about it crashing your
calc (if you chose to do it that way).
#include "ti86asm.inc"
#include "asm86.h"
#include "Ram86.inc"
#include "ti86abs.inc"
.org _asm_exec_ram
call _clrScrn
call _runindicoff
ld b,25
ld c,25
ld de,PIC
call PutSprite
Main_Prog:
call GET_KEY
cp K_EXIT
ret z
cp K_LEFT
jp z,LEFT
cp K_RIGHT
jp z,RIGHT
jp Main_Prog
LEFT:
inc b
call PutSprite
jp Main_Prog
RIGHT:
dec b
call PutSprite
jp Main_Prog
PIC:
.db %00111100
.db %01000010
.db %00111100
.db %00011000
.db %01111110
.db %00011000
.db %00100100
.db %01000010
PutSprite:
push bc ;Save BC (X,Y)
push de ;Save DE
push hl ;Save HL (Start of Sprite Data)
push hl
push bc
ld d,c
ld e,b
call FindPixel ;Finds pixel at E,D
pop bc
;PutSprite needs pixel at B,C
;A = Bitmask with one bit set; this will be the bit (pixel) "counter"
ex de,hl ;DE = Address in Display of Sprite
pop hl ;HL = Start of Sprite Data
ld b,(hl) ;B = X width of Sprite
inc hl ;Next byte
ld c,(hl) ;C = Y width of Sprite
inc hl ;Next byte (now pointing at actual sprite data)
push hl ;Save the twice incremented HL into stack
pop ix ;IX = The recently twice incremented HL
ex de,hl ;HL = Address in Display of Sprite
PS_NewRow:
push bc ;Save X width of Sprite and Y width of Sprite
ld d,(ix) ;D = (IX), so D = First byte from Sprite
inc ix ;IX points to next row
push af ;Save Bitmask
push hl ;Save HL, Address in Display of Sprite
PS_NewCol: ;Now the fun begins, remember a is the bitmask, D = the Left
Column Byte from Sprite
rl d ;Rotate D left through carry, Leftmost pixel of Sprite is carry
ld e,a ;E = bitmask
jr nc,PS_NoPixel ;Check pixel from sprite to see if it is set
or (hl) ;Sets Pixel at the "current bit" (Bitmask is the "bit counter")
ld (hl),a ;(HL) = A, Save changes to
jr PS_NextPixel
PS_NoPixel:
cpl ;Invert Bitmask
and (hl) ;Clears pixel at the "current bit" (Bitmask is the "bit counter")
ld (hl),a ;(HL) = A Save changes
PS_NextPixel:
ld a,e ;A = Bitmask
rrca ;A is rotated right *through* carry
jr nc,PS_SameByte ;If the carry was set, that means that one bit set in A
(bit counter)
; rotated all the way to the end right into carry and recycles back into
Bit 7
; so it can be used for the next byte
inc hl ;Go to the next byte in the display
PS_SameByte:
djnz PS_NewCol ;B = X (width of sprite), so it loops to PS_NewCol X times.
This means that is X = 6,
; it will Shift Right the bitmask (move the bit counter to the right) 6
times, comparing
; each bit of the bitmask and the sprite and setting or clearing the
pixel in that
; particular bit. It then moves on to the next pixel.
pop hl ;Recover HL, the Address in Display of the Sprite
pop af ;Recover AF, A = Bitmask
ld de,16 ;DE = 16
add hl,de ;HL = HL + 16, this moves down ONE row in the Display Area (128
width / (8 bit/pixel) = 16 bytes)
pop bc ;Recover X_width and Y_height of Sprite
dec c ;C = Y_height of Sprite, subtract one, which means on row of the
Sprite has been drawn
jr nz,PS_NewRow ;If there are more rows to be drawn, go back to PS_NewRow
; No more rows. Since there were "effectively" 3 pushes before PS_NewRow,
there must be three pops that way the
; ret statement will retrieve the correct address when it returns to the
calling program.
pop hl
pop de
pop bc
ret
; ========================================================
; Dan Eble & James Yopp FindPixel routine
; Input: D = y, E = x
; Output: HL = addr in vid mem, A = bitmask, C is modified
; ========================================================
FindPixel:
ld hl,FP_Bits
ld a,e
and $07 ;a = bit offset
add a,l
ld l,a
adc a,h
sub l
ld h,a
ld c,(hl) ;c = bitmask for (hl)
;48 t-states up to this point
ld hl,FP_RLD
ld (hl),d
ld a,e ;a = x/8 (byte offset within row)
rrca
rrca
rrca
rld
or $FC
ld l,(hl) ;hl -> byte in vid mem
ld h,a
ld a,c ;now a = bitmask for (hl)
;121 t-states up to this point
ret
FP_RLD:
.db $00
FP_Bits:
.db $80,$40,$20,$10,$08,$04,$02,$01
.end
THANX
Dan
P.S.-If you answer this now, I will probably not have another question for a
long time.
THANX
Follow-Ups: