453 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			453 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
%include ../include/gigatron.i
 | 
						|
 | 
						|
; 0x30 -> 0x38  Vars
 | 
						|
; 0x3A -> 0x45  Midi
 | 
						|
; 0x4A -> 0x96  CallTable   *DO NOT* pull CallTable above 0xBE, future ROMS will *NOT* work as the CallTable is preloaded and will conflict with future loading mechanisms
 | 
						|
; 0x98 -> 0xE5  Vars
 | 
						|
; 0xE6 -> 0xFF  Stack       The amount of stack space you will require depends on how many nested CALLS you make, 28 bytes allows for upto 14 nested calls
 | 
						|
 | 
						|
kk              EQU     0x30
 | 
						|
ll              EQU     kk + 0x01
 | 
						|
mm              EQU     kk + 0x02
 | 
						|
nn              EQU     kk + 0x03
 | 
						|
tt              EQU     kk + 0x04
 | 
						|
buttonStatePrev EQU     kk + 0x05
 | 
						|
refresh         EQU     kk + 0x06
 | 
						|
blocked         EQU     kk + 0x07
 | 
						|
tetrominoNext   EQU     kk + 0x08
 | 
						|
 | 
						|
midiStreamPtr   EQU     0x3A
 | 
						|
midiCommand     EQU     midiStreamPtr + 0x02
 | 
						|
midiChannel     EQU     midiStreamPtr + 0x04
 | 
						|
midiDelay       EQU     midiStreamPtr + 0x06
 | 
						|
midiNote        EQU     midiStreamPtr + 0x08
 | 
						|
midiScratch     EQU     midiStreamPtr + 0x0A
 | 
						|
 | 
						|
xx              EQU     0x98
 | 
						|
yy              EQU     xx + 0x01
 | 
						|
ii              EQU     xx + 0x02
 | 
						|
jj              EQU     xx + 0x03
 | 
						|
 | 
						|
index           EQU     xx + 0x04
 | 
						|
rotation        EQU     xx + 0x06
 | 
						|
indexNext       EQU     xx + 0x08
 | 
						|
rotationNext    EQU     xx + 0x0A
 | 
						|
tx              EQU     xx + 0x0C
 | 
						|
ty              EQU     xx + 0x0E
 | 
						|
tw              EQU     xx + 0x10
 | 
						|
th              EQU     xx + 0x12
 | 
						|
tu              EQU     xx + 0x14
 | 
						|
tv              EQU     xx + 0x16
 | 
						|
ox              EQU     xx + 0x18
 | 
						|
oy              EQU     xx + 0x1A
 | 
						|
ov              EQU     xx + 0x1C
 | 
						|
oindex          EQU     xx + 0x1E
 | 
						|
orotation       EQU     xx + 0x20
 | 
						|
tetrominoLut    EQU     xx + 0x22
 | 
						|
tetrominoBase   EQU     xx + 0x24
 | 
						|
colour          EQU     xx + 0x26
 | 
						|
result          EQU     xx + 0x28
 | 
						|
frameCounter    EQU     xx + 0x2A
 | 
						|
frameCountPrev  EQU     xx + 0x2C
 | 
						|
frameTicks      EQU     xx + 0x2E
 | 
						|
frameTicksLevel EQU     xx + 0x30
 | 
						|
rand            EQU     xx + 0x32
 | 
						|
scratch         EQU     xx + 0x34
 | 
						|
vbase           EQU     xx + 0x36
 | 
						|
xScroll         EQU     xx + 0x38
 | 
						|
tbase           EQU     xx + 0x3A
 | 
						|
dbase           EQU     xx + 0x3C
 | 
						|
textStr         EQU     xx + 0x3E
 | 
						|
textPos         EQU     xx + 0x40
 | 
						|
textChr         EQU     xx + 0x42
 | 
						|
numLines        EQU     xx + 0x44
 | 
						|
scoreDelta      EQU     xx + 0x46
 | 
						|
scoreLevel      EQU     xx + 0x48
 | 
						|
scoreUpdate     EQU     xx + 0x4A
 | 
						|
scoreScratch    EQU     xx + 0x4C
 | 
						|
 | 
						|
xTetris         EQU     10
 | 
						|
yTetris         EQU     20
 | 
						|
xPixels         EQU     xTetris*4
 | 
						|
yPixels         EQU     yTetris*4
 | 
						|
xOffset         EQU     (giga_xres - xPixels) / 2
 | 
						|
yOffset         EQU     (giga_yres - yPixels) / 2
 | 
						|
maxLines        EQU     4
 | 
						|
maxLevel        EQU     8
 | 
						|
maxTicks        EQU     50
 | 
						|
deltaTicks      EQU     5
 | 
						|
scorePos        EQU     0x6D44
 | 
						|
levelPos        EQU     0x6D5F
 | 
						|
highPos         EQU     0x1644
 | 
						|
multPos         EQU     0x6D3A
 | 
						|
fgColourB       EQU     0xFF
 | 
						|
bgColourB       EQU     0x15
 | 
						|
bgColourW       EQU     0x1515
 | 
						|
             
 | 
						|
_startAddress_      EQU     0x0200       ; entry point for the code, if this is missing defaults to 0x0200
 | 
						|
 | 
						|
_callTable_         EQU     0x0096       ; call addresses are automatically stored here by the assembler, it grows downwards
 | 
						|
                                         ; *NOTE* gt1 spec only allows for one zero page segment, .vasm files use this for the call table
 | 
						|
                                         ; do *NOT* make this address higher than 0x00BE, it will conflict with future ROM loading mechanisms
 | 
						|
                                         ; do *NOT* define constants, (DB or DW), between 0x30 -> 0x44 and 0xc0 -> 0xFF, these addresses are
 | 
						|
                                         ; used by the loader and the vCPU stack, you can create variables in these areas as long as you don't
 | 
						|
                                         ; corrupt your nested CALL return addresses on the stack
 | 
						|
                                        
 | 
						|
_singleStepWatch_   EQU     frameCounter ; the single step debugger watches this variable location to decide when to step,
 | 
						|
                                         ; choose a variable that is updated often
 | 
						|
_cpuUsageAddressA_  EQU     0x0600       ; these two addresses are used to build an exclusion zone around vCPU code that will not be counted
 | 
						|
_cpuUsageAddressB_  EQU     0x0620       ; in the vCPU usage meter, (almost always used to exclude your VBlank polling loop)
 | 
						|
 | 
						|
 | 
						|
%include midi_scores.i
 | 
						|
%include tetromino.i
 | 
						|
 | 
						|
scoringLut      EQU     tetromino_I + 0x0700
 | 
						|
levellingLut    EQU     tetromino_I + 0x0705
 | 
						|
scoringLut      DB      10 25 50 100
 | 
						|
levellingLut    DW      250 750 1000 2000 4000 8000 16000 32000 64000
 | 
						|
 | 
						|
score_string    EQU     0x7FA1
 | 
						|
high_string     EQU     0x7FA8
 | 
						|
level_string    EQU     0x7FAF
 | 
						|
mult_string     EQU     0x7FB2
 | 
						|
score_string    DB      6 '000000'
 | 
						|
high_string     DB      6 '000000'
 | 
						|
;level_string    DB      7 'LEVEL 0'
 | 
						|
; TODO: build a complete font set, right now ':' = 'L' and ';' = 'x'
 | 
						|
level_string    DB      2 ':0'
 | 
						|
mult_string     DB      2 ';1'
 | 
						|
 | 
						|
 | 
						|
; tetromino_I gets an extra slot to make rand easier to implement, this also means tetromino_I will appear statistically more often,
 | 
						|
; replace with which ever tetromino you want to favour
 | 
						|
tetromino_lut   EQU     0x08E0
 | 
						|
tetromino_lut   DW      tetromino_I tetromino_J tetromino_L tetromino_O tetromino_S tetromino_T tetromino_Z tetromino_I
 | 
						|
 | 
						|
 | 
						|
entry_point     EQU     0x0200
 | 
						|
handleInput     EQU     entry_point + 0x0100
 | 
						|
updateScore     EQU     entry_point + 0x0200        ; too big to store in unused area of video memory
 | 
						|
incrementScore  EQU     entry_point + 0x0300        ; too big to store in unused area of video memory
 | 
						|
waitVBlank      EQU     entry_point + 0x0400
 | 
						|
 | 
						|
 | 
						|
; storing subroutines in unused areas of video memory
 | 
						|
clearBoard      EQU     0x15A1
 | 
						|
clearScreen     EQU     clearBoard + 0x0100
 | 
						|
clearScreen_0   EQU     clearBoard + 0x0200
 | 
						|
setTetrisBlock  EQU     clearBoard + 0x0300
 | 
						|
drawTetromino   EQU     clearBoard + 0x0400
 | 
						|
drawNextTet     EQU     clearBoard + 0x0500
 | 
						|
drawTetrisField EQU     clearBoard + 0x0600
 | 
						|
drawTFtopH      EQU     clearBoard + 0x0700
 | 
						|
drawTFbotH      EQU     clearBoard + 0x0800
 | 
						|
eraseTetromino  EQU     clearBoard + 0x0900
 | 
						|
eraseTrCorner   EQU     clearBoard + 0x0A00
 | 
						|
getTetrisBlock  EQU     clearBoard + 0x0B00
 | 
						|
checkTetromino  EQU     clearBoard + 0x0C00
 | 
						|
spawnTetromino  EQU     clearBoard + 0x0D00
 | 
						|
updateTetromino EQU     clearBoard + 0x0E00
 | 
						|
checkLines      EQU     clearBoard + 0x0F00
 | 
						|
moveLines       EQU     clearBoard + 0x1000
 | 
						|
shakeScreen     EQU     clearBoard + 0x1100
 | 
						|
printText       EQU     clearBoard + 0x1200
 | 
						|
printDigits     EQU     clearBoard + 0x1300
 | 
						|
updateHighScore EQU     clearBoard + 0x1400
 | 
						|
resetLevel      EQU     clearBoard + 0x1500
 | 
						|
resetScore      EQU     clearBoard + 0x1600
 | 
						|
incrementLevel  EQU     clearBoard + 0x1700
 | 
						|
loadTetromino   EQU     clearBoard + 0x1800
 | 
						|
resetAudio      EQU     clearBoard + 0x1900
 | 
						|
playMidi        EQU     clearBoard + 0x1A00
 | 
						|
midiStartNote   EQU     clearBoard + 0x1B00
 | 
						|
midiSegment     EQU     clearBoard + 0x1C00
 | 
						|
 | 
						|
 | 
						|
%include macros.i
 | 
						|
%include clear_board.i
 | 
						|
%include draw_tetromino.i
 | 
						|
%include erase_tetromino.i
 | 
						|
%include check_tetromino.i
 | 
						|
%include spawn_tetromino.i
 | 
						|
%include check_lines.i
 | 
						|
%include print_text.i
 | 
						|
%include update_score.i
 | 
						|
%include digit_font.i
 | 
						|
%include audio.i
 | 
						|
 | 
						|
 | 
						|
entry_point     LDWI    giga_vram
 | 
						|
                STW     vbase               ; vram base address
 | 
						|
                LDWI    giga_text32
 | 
						|
                STW     tbase               ; text font base address, (ROM)
 | 
						|
                LDWI    digit_font0         
 | 
						|
                STW     dbase               ; tiny digit font base address, (RAM)
 | 
						|
                LDWI    giga_videoTable + 1
 | 
						|
                STW     xScroll
 | 
						|
 | 
						|
                CALL    resetAudio
 | 
						|
                CALL    clearScreen
 | 
						|
                CALL    drawTetrisField
 | 
						|
 | 
						|
restart         CALL    resetLevel
 | 
						|
                CALL    resetScore
 | 
						|
                CALL    clearBoard 
 | 
						|
 | 
						|
                LDWI    0x0000
 | 
						|
                STW     scoreDelta
 | 
						|
                STW     scoreLevel
 | 
						|
                STW     frameCounter    
 | 
						|
 | 
						|
                LDWI    maxTicks
 | 
						|
                STW     frameTicksLevel
 | 
						|
                STW     frameTicks
 | 
						|
 | 
						|
                LD      giga_rand0
 | 
						|
                ST      tetrominoNext
 | 
						|
 | 
						|
                LDI     0x00
 | 
						|
                ST      blocked
 | 
						|
                
 | 
						|
                LD      giga_frameCount
 | 
						|
                STW     frameCountPrev
 | 
						|
 | 
						|
                LDWI    tetromino_lut
 | 
						|
                STW     tetrominoLut
 | 
						|
                     
 | 
						|
                CALL    spawnTetromino
 | 
						|
                
 | 
						|
                LD      giga_frameCount ; Start checking midi stream immediately
 | 
						|
                ST      midiDelay
 | 
						|
                
 | 
						|
                ; main update loop
 | 
						|
update          ST      scratch
 | 
						|
                CALL    saveTetromino
 | 
						|
 | 
						|
                ; wait for VBlank
 | 
						|
vBlank          CALL    waitVBlank
 | 
						|
                CALL    playMidi
 | 
						|
                
 | 
						|
                ; input
 | 
						|
                CALL    handleInput
 | 
						|
                ST      refresh
 | 
						|
                XORI    0xFB            ; down
 | 
						|
                BEQ     frame_count1
 | 
						|
                LD      refresh         ; all other input
 | 
						|
                BNE     erase
 | 
						|
 | 
						|
                ; reset frameTicks
 | 
						|
                LDW     frameTicksLevel
 | 
						|
                STW     frameTicks
 | 
						|
 | 
						|
                ; frameTicks defines speed of tetrominoes
 | 
						|
frame_count1    LDW     frameCounter
 | 
						|
                ADDI    0x01
 | 
						|
                STW     frameCounter
 | 
						|
                SUBW    frameTicks
 | 
						|
                BLT     vBlank
 | 
						|
 | 
						|
                ; don't allow input to override timing
 | 
						|
                LDI     0x00
 | 
						|
                ST      refresh
 | 
						|
 | 
						|
                ; erase old tetromino
 | 
						|
erase           LD      blocked
 | 
						|
                BNE     check_txl
 | 
						|
                CALL    eraseTetromino
 | 
						|
 | 
						|
                ; if(tx < 0 - tu) tx = 0 - tu;
 | 
						|
check_txl       LDW     tx              
 | 
						|
                ADDW    tu
 | 
						|
                BGE     check_txr
 | 
						|
                LDWI    0x00
 | 
						|
                SUBW    tu
 | 
						|
                STW     tx
 | 
						|
                BRA     frame_count0
 | 
						|
 | 
						|
                ; if(tx > TETRIS_XEXT - tw - tu) tx = TETRIS_XEXT - tw - tu;
 | 
						|
check_txr       LDW     tx              
 | 
						|
                ADDW    tw
 | 
						|
                ADDW    tu
 | 
						|
                SUBI    xTetris
 | 
						|
                BLE     frame_count0
 | 
						|
                LDWI    xTetris
 | 
						|
                SUBW    tw
 | 
						|
                SUBW    tu
 | 
						|
                STW     tx
 | 
						|
 | 
						|
                ; if(frameCount >= frameTick)
 | 
						|
frame_count0    LDW     frameCounter    
 | 
						|
                SUBW    frameTicks
 | 
						|
                BLT     check_blocks
 | 
						|
                LDWI    0x0000
 | 
						|
                STW     frameCounter   
 | 
						|
                LDI     0x00            ; reset flicker control                
 | 
						|
                ST      blocked
 | 
						|
 | 
						|
                ; gravity    
 | 
						|
                INC     ty                  
 | 
						|
 | 
						|
                ; if(y > TETRIS_YEXT - h)
 | 
						|
                LDW     ty
 | 
						|
                ADDW    th
 | 
						|
                SUBI    yTetris
 | 
						|
                BLE     check_blocks
 | 
						|
 | 
						|
                ; draw floor tetromino
 | 
						|
                LD      ty
 | 
						|
                SUBI    0x01
 | 
						|
                ST      ty
 | 
						|
                CALL    drawTetromino 
 | 
						|
 | 
						|
                ; spawn new tetromino
 | 
						|
                CALL    spawnTetromino
 | 
						|
                LDI     0xFF            ; control flicker
 | 
						|
                ST      blocked
 | 
						|
                BRA     update
 | 
						|
 | 
						|
                ; check new tetromino position
 | 
						|
check_blocks    CALL    checkTetromino      ; checks tetromino for occupied blocks, returns result, 0 = empty, 1 = game over, >1 = blocked
 | 
						|
                LDW     result
 | 
						|
                BEQ     draw_new
 | 
						|
 | 
						|
                ; check for game over
 | 
						|
                SUBI    0x01
 | 
						|
                BNE     check_blocked
 | 
						|
                CALL    resetAudio
 | 
						|
                LDWI    game_overMidi00     ; game over music
 | 
						|
                STW     midiStreamPtr 
 | 
						|
                BRA     restart
 | 
						|
 | 
						|
                ; check for fall blocked whilst input active, (but not drop)
 | 
						|
check_blocked   LD      refresh
 | 
						|
                BEQ     fall_blocked
 | 
						|
 | 
						|
                ; load old tetromino
 | 
						|
                CALL    loadTetromino
 | 
						|
                BRA     draw_new
 | 
						|
 | 
						|
                ; draw falling blocked tetromino at previous y position
 | 
						|
fall_blocked    LD      ty
 | 
						|
                SUBI    0x01
 | 
						|
                ST      ty
 | 
						|
                CALL    drawTetromino 
 | 
						|
 | 
						|
                ; spawn new tetromino
 | 
						|
                CALL    spawnTetromino
 | 
						|
                BRA     update
 | 
						|
 | 
						|
draw_new        CALL    drawTetromino 
 | 
						|
                BRA     update
 | 
						|
 | 
						|
                
 | 
						|
                ; load tetromino state
 | 
						|
loadTetromino   LDW     ox          
 | 
						|
                STW     tx
 | 
						|
                LDW     oy          
 | 
						|
                STW     ty
 | 
						|
                LDW     ov              ; vertical offset in tetris block units
 | 
						|
                STW     tv
 | 
						|
                LDW     oindex
 | 
						|
                STW     index
 | 
						|
                LDW     orotation
 | 
						|
                STW     rotation
 | 
						|
                RET
 | 
						|
 | 
						|
                ; save tetromino state
 | 
						|
saveTetromino   LDW     tx          
 | 
						|
                STW     ox
 | 
						|
                LDW     ty          
 | 
						|
                STW     oy
 | 
						|
                LDW     tv              ; vertical offset in tetris block units
 | 
						|
                STW     ov
 | 
						|
                LDW     index
 | 
						|
                STW     oindex
 | 
						|
                LDW     rotation
 | 
						|
                STW     orotation
 | 
						|
                RET
 | 
						|
 | 
						|
 | 
						|
                ; handle input, returns 0x00 if nothing was handled, otherwise returns input
 | 
						|
handleInput     LD      giga_buttonState     ; 0xFF is no input
 | 
						|
                XORI    0xFF
 | 
						|
                BNE     handleI_down
 | 
						|
                ST      buttonStatePrev ; return 0x00     
 | 
						|
                RET
 | 
						|
 | 
						|
                ; level triggered buttons
 | 
						|
handleI_down    LD      giga_buttonState
 | 
						|
                XORI    0xFB            ; down
 | 
						|
                BNE     handleI_event
 | 
						|
                LDWI    2
 | 
						|
                STW     frameTicks
 | 
						|
                LD      giga_buttonState
 | 
						|
                RET
 | 
						|
 | 
						|
                ; edge triggering
 | 
						|
handleI_event   LD      buttonStatePrev ; only handle new events
 | 
						|
                BEQ     handleI_left
 | 
						|
                LD      0x00
 | 
						|
                RET
 | 
						|
 | 
						|
                ; edge triggered buttons
 | 
						|
handleI_left    LD      giga_buttonState
 | 
						|
                ST      buttonStatePrev
 | 
						|
                XORI    0xFD            ; left
 | 
						|
                BNE     handleI_right
 | 
						|
 | 
						|
                LDW     tx              ; tx--
 | 
						|
                SUBI    0x01
 | 
						|
                STW     tx
 | 
						|
                LD      giga_buttonState
 | 
						|
                RET
 | 
						|
 | 
						|
handleI_right   LD      giga_buttonState
 | 
						|
                XORI    0xFE            ; right
 | 
						|
                BNE     handleI_up
 | 
						|
 | 
						|
                LDW     tx              ; tx++
 | 
						|
                ADDI    0x01
 | 
						|
                STW     tx
 | 
						|
                LD      giga_buttonState
 | 
						|
                RET
 | 
						|
 | 
						|
handleI_up      LD      giga_buttonState
 | 
						|
                XORI    0xF7            ; up
 | 
						|
                BNE     handleI_exit
 | 
						|
 | 
						|
                LDW     rotation
 | 
						|
                STW     scratch
 | 
						|
                ADDI    0x10            ; rotation table's are separated by 16 bytes
 | 
						|
                ANDI    0x30            ; 4 rotation patterns
 | 
						|
                STW     rotation
 | 
						|
                PUSH
 | 
						|
                CALL    updateTetromino
 | 
						|
                POP
 | 
						|
 | 
						|
                ; check rotation
 | 
						|
                LDW     ty              ; if(ty > TETRIS_YEXT - th - tv)
 | 
						|
                ADDW    th
 | 
						|
                ADDW    tv
 | 
						|
                SUBI    yTetris
 | 
						|
                BLE     handleI_exit
 | 
						|
 | 
						|
                ; restore rotation
 | 
						|
                LDW     scratch
 | 
						|
                STW     rotation
 | 
						|
                PUSH
 | 
						|
                CALL    updateTetromino
 | 
						|
                POP
 | 
						|
                LD      0x00
 | 
						|
                RET
 | 
						|
 | 
						|
handleI_exit    LD      giga_buttonState
 | 
						|
                RET
 | 
						|
 | 
						|
 | 
						|
waitVBlank      LD      giga_frameCount
 | 
						|
                SUBW    frameCountPrev
 | 
						|
                BEQ     waitVBlank
 | 
						|
                LD      giga_frameCount
 | 
						|
                STW     frameCountPrev
 | 
						|
                RET |