Created
December 13, 2011 03:26
-
-
Save cbmeeks/1470406 to your computer and use it in GitHub Desktop.
Commodore 64 full screen asm scroller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Imports | |
.import source "../engine/vars.asm" | |
.import source "../engine/interrupts.asm" | |
.import source "../engine/map.asm" | |
.import source "../engine/misc.asm" | |
.import source "../engine/screen.asm" | |
.import source "../engine/sprites.asm" | |
.var XPIXSHIFT = 4 | |
.var TIMER = 5 | |
.pc = $0801 "Basic Upstart" | |
:BasicUpstart(start) | |
.pc = $4000 "Main Program" | |
start: | |
// set default map data | |
lda #<MAP_DATA | |
sta MAP_PTRL | |
lda #>MAP_DATA | |
sta MAP_PTRH | |
lda #3 // 3 rooms wide | |
sta MAP_WIDTH | |
lda #0 | |
sta MAP_X | |
sta MAP_Y | |
lda #0 | |
sta TILE_SIDE | |
lda #7 | |
sta SCR_X_POS | |
lda SCR_X_POS | |
and #7 | |
ora #16 | |
sta $D016 | |
lda #0 | |
sta Y_TEMP | |
lda #0 | |
sta MAP_COL_NUM | |
:SetVICBank0() | |
:SetScreenAndCharLocation(SCRBUFFER, CHARSET) | |
:ClearScreen(SCRBUFFER, 0) | |
:ClearScreen(DBLBUFFER, 0) | |
:ClearColorRam(10) | |
:SetBorderColor(BLACK) | |
:SetBackgroundColor(BLACK) | |
:SetMultiColor1(LIGHT_BLUE) | |
:SetMultiColor2(BLUE) | |
:SetMultiColorMode() | |
// :SetScrollMode() | |
lda #FLIP_BUF_COUNT | |
sta FLIP_COUNTER | |
:SetScreenAndCharLocation(SCRBUFFER, CHARSET) // $3400 visible at this point | |
lda #<SCRBUFFER | |
sta CURBUFFER_PTRL | |
lda #>SCRBUFFER | |
sta CURBUFFER_PTRH | |
lda #<DBLBUFFER | |
sta DBLBUFFER_PTRL | |
lda #>DBLBUFFER | |
sta DBLBUFFER_PTRH | |
jsr startdrawmap // draw initial map | |
lda #1 | |
sta CURBUFFER | |
jsr flipbuffer | |
lda #60 // initial delay | |
sta TEMP1 | |
// jsr shiftleft | |
:SetupIRQ(0, counters) | |
main: | |
jmp main | |
counters: | |
:BeginInterrupt() | |
dec TEMP1 | |
bne !exit+ | |
lda #1 | |
sta TEMP1 | |
// 7-6 Unused | |
// | |
// 5 ALWAYS SET THIS BIT TO 0 ! | |
// | |
// 4 Multi-Color Mode: 1 = Enable (Text or | |
// Bit-Map); | |
// 3 Select 38/40 Column Text Display: | |
// 1 = 40 Cols | |
// 2-0 Smooth Scroll to X Pos | |
lda SCR_X_POS | |
and #7 | |
ora #16 | |
sta $D016 | |
dec SCR_X_POS | |
lda SCR_X_POS | |
cmp #0 | |
bne !exit+ | |
jsr shiftleft | |
lda #7 | |
sta SCR_X_POS | |
lda SCR_X_POS | |
and #7 | |
ora #16 | |
sta $D016 | |
!exit: | |
:ReturnFromInterrupt() | |
shiftleft: | |
!draw_right_edge: | |
lda DBLBUFFER_PTRL // grab the DBLBUFFER_PTR | |
sta DLBBUFFER_EDGE_PTRL // and add 39 chars | |
lda DBLBUFFER_PTRH // so that we are on the RIGHT side | |
sta DLBBUFFER_EDGE_PTRH // of the screen | |
clc | |
lda DLBBUFFER_EDGE_PTRL // jump to the RIGHT edge | |
adc #39 | |
sta DLBBUFFER_EDGE_PTRL | |
bcc *+4 | |
inc DLBBUFFER_EDGE_PTRH | |
ldx #12 // number of tile rows to draw | |
stx MAP_ROW | |
lda MAP_COL_NUM // Y holds the offset of the room's map in tiles | |
sta Y_TEMP // so that 0 means upper-left of map, 240 lower right | |
!loop: | |
lda Y_TEMP | |
tay | |
lda (MAP_PTRL), y // A contains tile | |
tax // move tile number to X | |
clc // inc Y_TEMP by 20 | |
lda Y_TEMP // so that next time we jump down a row in the map | |
adc #20 | |
sta Y_TEMP | |
!continue: | |
lda TILE_SIDE // which side of the tile are we drawing? | |
beq !draw_left_side+ | |
jmp !draw_right_side+ | |
!draw_left_side: | |
ldy #0 | |
lda TileCharLookupA, x // A now contains upper left char from tile | |
sta (DLBBUFFER_EDGE_PTRL), y // draw char on edge | |
ldy #40 | |
lda TileCharLookupC, x // A now contains the lower left char from tile | |
sta (DLBBUFFER_EDGE_PTRL), y // draw char on edge | |
jmp !continue+ | |
!draw_right_side: | |
ldy #0 | |
lda TileCharLookupB, x // A now contains upper right char from tile | |
sta (DLBBUFFER_EDGE_PTRL), y // draw char on edge | |
ldy #40 | |
lda TileCharLookupD, x // A now contains the lower right char from tile | |
sta (DLBBUFFER_EDGE_PTRL), y // draw char on edge | |
!continue: | |
clc | |
lda DLBBUFFER_EDGE_PTRL // jump down two rows (loop unrolled with 2x2 tile) | |
adc #80 | |
sta DLBBUFFER_EDGE_PTRL | |
bcc *+4 | |
inc DLBBUFFER_EDGE_PTRH | |
dec MAP_ROW // dec the row counter | |
bne !loop- // loop back if not at bottom | |
!start_screen_shift: | |
ldx #24 // Number of ROWS | |
ldy #38 // Number of COLUMNS | |
inc CURBUFFER_PTRL // shift over one char | |
!loop_shift: | |
lda (CURBUFFER_PTRL), y | |
sta (DBLBUFFER_PTRL), y | |
dey | |
bne !loop_shift- | |
lda (CURBUFFER_PTRL), y // load last char (0 actually) | |
sta (DBLBUFFER_PTRL), y // draw it | |
clc | |
lda CURBUFFER_PTRL // jump down to next line for the current buffer | |
adc #40 | |
sta CURBUFFER_PTRL | |
bcc *+4 | |
inc CURBUFFER_PTRH | |
clc | |
lda DBLBUFFER_PTRL // jump down to the next line for the double buffer | |
adc #40 | |
sta DBLBUFFER_PTRL | |
bcc *+4 | |
inc DBLBUFFER_PTRH | |
ldy #38 // reset Y | |
dex // dec X | |
bne !loop_shift- // have we reached the bottom? | |
jsr flipbuffer // flip buffers and reveal new content | |
lda TILE_SIDE // toggle tile side | |
eor #$01 | |
sta TILE_SIDE | |
lda TILE_SIDE // OK, we just finished drawing a CHAR column | |
bne !exit+ // did we just toggle to the LEFT side? If so, | |
// then we are on a new ROOM column | |
inc MAP_COL_NUM | |
lda MAP_COL_NUM // Have we reached the end of a room column? (20) | |
cmp #20 // If so, reset back to 0 so that we don't | |
bcc !exit+ // get garbage room data. | |
lda #0 // also, at this point, we need to check the WORLD MAP | |
sta MAP_COL_NUM // to see what the next room number is....TBD | |
clc // for now, bump to the next room in ram | |
lda MAP_PTRL | |
adc #240 | |
sta MAP_PTRL | |
bcc *+4 | |
inc MAP_PTRH // this section needs to be replaced with WORLD MAP DATA | |
!exit: | |
rts // return | |
flipbuffer: | |
lda CURBUFFER | |
beq !flip+ // SCRBUFFER (compares to 0) | |
lda #<SCRBUFFER // make SCRBUFFER the visible buffer | |
sta CURBUFFER_PTRL | |
lda #>SCRBUFFER | |
sta CURBUFFER_PTRH | |
lda #<DBLBUFFER // make DBLBUFFER the hidden buffer | |
sta DBLBUFFER_PTRL | |
lda #>DBLBUFFER | |
sta DBLBUFFER_PTRH | |
lda #[[SCRBUFFER & $3FFF] / 64] | [[CHARSET & $3FFF] / 1024] | |
sta $D018 | |
!exit: | |
lda CURBUFFER | |
eor #$01 | |
sta CURBUFFER | |
rts | |
!flip: | |
lda #<DBLBUFFER // make DBLBUFFER the visible buffer | |
sta CURBUFFER_PTRL | |
lda #>DBLBUFFER | |
sta CURBUFFER_PTRH | |
lda #<SCRBUFFER // make SCRBUFFER the hidden buffer | |
sta DBLBUFFER_PTRL | |
lda #>SCRBUFFER | |
sta DBLBUFFER_PTRH | |
lda #[[DBLBUFFER & $3FFF] / 64] | [[CHARSET & $3FFF] / 1024] | |
sta $D018 | |
!exit: | |
lda CURBUFFER | |
eor #$01 | |
sta CURBUFFER | |
rts | |
startdrawmap: | |
lda #0 // Reset Row/Col | |
sta ColumnNumber | |
sta RowNumber | |
ldx #0 | |
drawmap: | |
!loop: | |
ldy #0 | |
lax (MAP_PTRL), y // X now contains tile number (from Map Data) $AF | |
lda TileCharLookupA, x // A now contains upper left char from tile | |
sta (CURBUFFER_PTRL), y // draw upper-left of tile | |
lda TileCharLookupB, x // A now contains upper-right char from tile | |
ldy #1 | |
sta (CURBUFFER_PTRL), y // draw upper-right char from tile | |
lda TileCharLookupC, x // A now contains lower-left char from tile | |
ldy #40 // jump down to next line in screen buffer | |
sta (CURBUFFER_PTRL), y // draw lower-left char from tile | |
lda TileCharLookupD, x // A now contains lower-right char from tile | |
ldy #41 | |
sta (CURBUFFER_PTRL), y // draw lower-right char from tile | |
clc // clear the carry bit | |
lda CURBUFFER_PTRL // screen buffer | |
adc #2 // add 2 to screen buffer (since our tiles are 2x2) | |
sta CURBUFFER_PTRL // update the screen buffer pointer | |
bcc *+4 // skip the next instruction if C is clear (didn't roll over) | |
inc CURBUFFER_PTRH // we rolled over so increase the HIGH byte (ie, $34FE + 2 = $3500) | |
inc MAP_PTRL // move to the next map data position | |
inc ColumnNumber // move to the next column | |
lda ColumnNumber // load the column number | |
cmp #20 // have we reached the right side? | |
bne !loop- // not yet...repeat loop | |
lda #0 // yes, now reset the column number | |
sta ColumnNumber // and store it. | |
clc // clear carry | |
lda CURBUFFER_PTRL // jump down to the next row | |
adc #40 // add 40 (jumps down a row) | |
sta CURBUFFER_PTRL // update current buffer pointer | |
bcc *+4 // have we rolled over? | |
inc CURBUFFER_PTRH // yes so increase the high byte | |
inc RowNumber // increase the row number | |
lda RowNumber // load current row number | |
cmp #12 // have we reached the bottom of the screen? | |
bne drawmap // no, continue drawing the next row | |
rts // yes, return | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.var charname = "../51 pegasus/gfx/chars.raw" | |
.var room001_name = "../51 pegasus/rooms/room001" | |
.var room002_name = "../51 pegasus/rooms/room002" | |
.var room003_name = "../51 pegasus/rooms/room003" | |
.var room004_name = "../51 pegasus/rooms/room004" | |
.var room005_name = "../51 pegasus/rooms/room005" | |
.var room006_name = "../51 pegasus/rooms/room006" | |
.var tilename = "../51 pegasus/gfx/tiles.raw" | |
// variables ZP = $10 - $28 | |
.var RowNumber = $10 | |
.var ColumnNumber = $11 | |
// Chars ZP = $29 - $39 | |
.var CHARSET = $2000 | |
.var CURRENT_TILE = $29 | |
// Lookups | |
.var LOOKUPS = $C100 // ; various lookup tables | |
// Map ZP = $3A - $4F | |
// .var WORLD_DATA = $400 | |
.var MAP_DATA = $C400 | |
.var MAP_PTRL = $3A | |
.var MAP_PTRH = $3B | |
.var ROOM_PTRL = $3C | |
.var ROOM_PTRH = $3D | |
.var CUR_TILE = $3E | |
.var MAP_ROW = $3F | |
.var MAP_COL_NUM = $40 | |
.var MAP_WIDTH = $41 // in ROOMS | |
.var MAP_HEIGHT = $42 | |
.var MAP_X = $43 // position in tiles | |
.var MAP_Y = $44 | |
.var NUM_TILES = 64 | |
// Screen ZP = $50 - $70 | |
.var FLIP_COUNTER = $50 | |
.var FLIP_BUF_COUNT = 40 | |
.var CURBUFFER_PTRL = $52 // the address of the current buffer (SCR or DBL) which is shown | |
.var CURBUFFER_PTRH = $53 | |
.var DBLBUFFER_PTRL = $54 | |
.var DBLBUFFER_PTRH = $55 | |
.var DLBBUFFER_EDGE_PTRL = $56 | |
.var DLBBUFFER_EDGE_PTRH = $57 | |
.var SCR_X_POS = $58 | |
.var SCR_Y_POS = $59 | |
.var CURBUFFER = $67 // 0 = SCREENBUFFER 1 = DBLBUFFER | |
.var SCRBUFFER = $3400 | |
.var DBLBUFFER = $3800 | |
// Temp | |
.var TEMP1 = $70 | |
.var TEMP2 = $71 | |
.var X_TEMP = $72 | |
.var Y_TEMP = $73 | |
// Tiles ZP = ?? | |
.var TILE_SIDE = $74 | |
.var TILES_DATA = $C000 | |
// Character Set | |
.pc = CHARSET "Chars" | |
.var chars = LoadBinary(charname) | |
.fill chars.getSize(), chars.get(i) | |
// Lookup Tables | |
.pc = LOOKUPS "Various Lookups" | |
TileCharLookupA: .for(var i=0; i < NUM_TILES; i++) .byte i * 4 | |
TileCharLookupB: .for(var i=0; i < NUM_TILES; i++) .byte [i * 4] + 1 | |
TileCharLookupC: .for(var i=0; i < NUM_TILES; i++) .byte [i * 4] + 2 | |
TileCharLookupD: .for(var i=0; i < NUM_TILES; i++) .byte [i * 4] + 3 | |
RoomNumberLookup: .word MAP_DATA + [0 * 240], MAP_DATA + [1 * 240], MAP_DATA + [2 * 240] | |
// Map (Room) Data | |
.pc = MAP_DATA | |
.var room001 = LoadBinary(room001_name) | |
.fill room001.getSize(), room001.get(i) | |
.var room002 = LoadBinary(room002_name) | |
.fill room002.getSize(), room002.get(i) | |
.var room003 = LoadBinary(room003_name) | |
.fill room003.getSize(), room003.get(i) | |
.var room004 = LoadBinary(room004_name) | |
.fill room004.getSize(), room004.get(i) | |
.var room005 = LoadBinary(room005_name) | |
.fill room005.getSize(), room005.get(i) | |
.var room006 = LoadBinary(room006_name) | |
.fill room006.getSize(), room006.get(i) | |
// Tiles | |
.pc = TILES_DATA "Tiles" | |
.var tilesdata = LoadBinary(tilename) | |
.fill tilesdata.getSize(), tilesdata.get(i) | |
// World | |
// .pc = WORLD_DATA "World Data" | |
// .byte 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment