Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // This is a test for a line by line fill / copy routine. Intention was to gradually copy in a gfx
- // from buffer 1 (not visible) to buffer 2 (vibisble). For some reason the copy does not start on the
- // first pixel/byte on every line.
- //
- // The lines are "randomised" over the 200 lines in the hires display.
- //
- // Rather than go pixel by pixel, I was going to copy a full byte in the x direction to set 8 pixels
- // in one go. That seems to work, but.. there's something else going on...
- .var vic_bank_2=2 // vic bank 2 = 32768 ($8000-$BFFF)
- .var vic_base_2=$4000*vic_bank_2 // a VIC-II bank indicates a 16K region
- .var screen_memory_2=$0c00 + vic_base_2 // screen memory = 3072 + 32768 = 35840 (0x8c00)
- .var bitmap_address_2=$2000 + vic_base_2 // bitmap address = 40960 (0xa000)
- .var text_mode_screen_memory_2=vic_base_2 // text memory = $8000. Charset in $1000 which is in bank 2 mapped to character rom
- .var vic_bank_3=3
- .var vic_base_3=$4000*vic_bank_3
- .var screen_memory_3=$0c00 + vic_base_3
- .var bitmap_address_3=$2000 + vic_base_3
- .var text_mode_screen_memory_3=vic_base_3
- // The bitmap pointer has to reside in zero page because of the indirect addressing mode used. Screen buffer #1.
- .const bitmap_pointer = $32
- .const screen_color_pointer = $34
- // IRQ Interupt setup
- .const part_1_irq0line = 30
- .const part_1_irq1line = 245
- .const part_1_irq2line = 246
- .const part_2_irq0line = 16
- .const part_2_textmodeswitchline = 17
- .const part_2_rastercolorline = 18
- // Screen & border registers
- .label border_color = $d020
- .label screen_color = $d021
- // ZERO PAGE VARIABLE : These are pointers used for the
- .const ScreenBuffer2_part1_lo=$32
- .const ScreenBuffer2_part1_hi=$33
- .const ScreenBuffer2_part2_lo=$34
- .const ScreenBuffer2_part2_hi=$35
- .const BitmapBuffer2_part1_lo=$36
- .const BitmapBuffer2_part1_hi=$37
- .const BitmapBuffer2_part2_lo=$38
- .const BitmapBuffer2_part2_hi=$39
- .const ScreenColorBuffer2_part1_lo=$4a
- .const ScreenColorBuffer2_part1_hi=$4b
- .const ScreenColorBuffer2_part2_lo=$4c
- .const ScreenColorBuffer2_part2_hi=$4d
- .const BitmapColorBuffer2_part1_lo=$4e
- .const BitmapColorBuffer2_part1_hi=$4f
- .const BitmapColorBuffer2_part2_lo=$50
- .const BitmapColorBuffer2_part2_hi=$51
- // Gradually display logo routine - ZP pointers used to gradually display the logo in screen buffer
- .const Copy_Logo_Y_Lo=$52
- .const Copy_Logo_Y_Hi=$53
- .const Copy_Logo_X_Lo=$54
- .const Copy_Logo_X_Hi=$55
- .const Copy_Logo_Colors_Y_Lo=$52
- .const Copy_Logo_Colors_Y_Hi=$53
- .const Copy_Logo_Colors_X_Lo=$54
- .const Copy_Logo_Colors_X_Hi=$55
- .const Copy_Bitmap_Y_Lo=$56
- .const Copy_Bitmap_Y_Hi=$57
- .const Copy_Bitmap_X_Lo=$58
- .const Copy_Bitmap_X_Hi=$59
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- // MAIN CODE
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- BasicUpstart2(start)
- start:
- jsr init_data_variables
- main_loop:
- lda #%00000010
- eor active_demo_part
- and #%00000010
- beq demo_part_2
- jmp check_demo_part_end
- demo_part_2:
- // Demo part #2 - code here
- jsr demo_section_part_2
- jmp check_demo_part_end
- check_demo_part_end:
- jmp main_loop
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- // PART 2
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- demo_section_part_2: {
- SwitchVICBank(vic_bank_3)
- SetHiresBitmapMode()
- SetScreenMemory(screen_memory_3 - vic_base_3)
- SetBitmapAddress(bitmap_address_3 - vic_base_3)
- // Clear out both screen & color buffers
- FillBitmap(bitmap_address_2, $00)
- FillScreenMemory(screen_memory_2, $f0)
- FillBitmap(bitmap_address_3, $00)
- FillScreenMemory(screen_memory_3, $f0)
- lda #BLACK
- sta border_color
- sta screen_color
- // IRQ setup - part 2
- sei
- // This causes the CPU to see RAM instead of KERNAL and
- // BASIC ROM at $E000-$FFFF and $A000-$BFFF respectively.
- //
- // This causes the CPU to see RAM everywhere except for
- // $D000-$E000, where the VIC-II, SID, CIA's etc are located.
- lda #$35
- sta $01
- // Setup raster IRQ
- SetupIRQ(irq_part2_0, part_2_irq0line, false)
- cli
- ldy #0
- sty Random200Numbers_Active // store the active line number that the sub routine will pick up and use to copy the logo line
- copy_another_line:
- // lets load the line number reference (we are counting down from 199 to 0 here, which will be used to pick up a number from a randomized line list next)
- ldy Random200Numbers_Active
- // lets use the reference number to pick the actual line number that we will copy next.. this list is randomized on every compile
- lda Random200Numbers,y
- tay
- // Source: Set up the ZP reference for the DZ logo which resides in memory somewhere
- lda Copy_Logo_Y_Table_Lo,y
- sta Copy_Logo_Y_Lo
- lda Copy_Logo_Y_Table_Hi,y
- sta Copy_Logo_Y_Hi
- // Destination: Set up the ZP reference for the current screen buffer that is displayed
- lda Copy_Bitmap_Y_Table_Lo,y
- sta Copy_Bitmap_Y_Lo
- lda Copy_Bitmap_Y_Table_Hi,y
- sta Copy_Bitmap_Y_Hi
- // We are copying 40 bytes across the x-axis - hence lets set x=40 and dex to zero and test
- ldx #0
- copy_more_line_bytes:
- // We now need to populate the ZP pointers for the X-value. These are the same offsets for every X value on any Y line.
- // We have to then add the lo/hi byte to the Y starting address for every byte, which then has the correct pointer that we
- // need to use to find the right byte in the buffer ..
- //.const Copy_Logo_X_Lo=$54
- //.const Copy_Logo_X_Hi=$55
- //.const Copy_Bitmap_X_Lo=$58
- //.const Copy_Bitmap_X_Hi=$59
- ldy Copy_Bitmap_X_Table_Lo,x
- sty num1lo
- ldy Copy_Bitmap_X_Table_Hi,x
- sty num1hi
- ldy Copy_Bitmap_Y_Lo
- sty num2lo
- ldy Copy_Bitmap_Y_Hi
- sty num2hi
- jsr add_16_bit
- ldy resultlo
- sty Copy_Bitmap_X_Lo
- ldy resulthi
- sty Copy_Bitmap_X_Hi
- ldy Copy_Logo_X_Table_Lo,x
- sty num1lo
- ldy Copy_Logo_X_Table_Hi,x
- sty num1hi
- ldy Copy_Logo_Y_Lo
- sty num2lo
- ldy Copy_Logo_Y_Hi
- sty num2hi
- jsr add_16_bit
- ldy resultlo
- sty Copy_Logo_X_Lo
- ldy resulthi
- sty Copy_Logo_X_Hi
- // we now have both the logo and bitmap pointers updated for the current X value and we can proceed with copying the byte
- // we need to put in a delay here, or else it will transition in too fast..
- jsr time_delay_1
- // lets load $ff as we are setting all 8 bits/pixels in one go. We are intending to copy byte by byte from source to destination line by line
- lda #%11111111
- sta (Copy_Bitmap_X_Lo),y
- // lets decrement the X byte that we are copying in.. when we get to 0 we have completed copying a line and we move on
- inx
- cpx #40
- bne copy_more_line_bytes
- // we need to put in a delay here, or else it will transition in too fast..
- jsr time_delay_1
- inc Random200Numbers_Active
- ldx Random200Numbers_Active
- cpx #200
- bcc copy_another_line
- CopyBitmap(bitmap_address_3, bitmap_address_2)
- // set the switch to move on from this setup part to the next demo part
- lda #%00000100
- sta active_demo_part // which demo part is active - starting on part 1
- rts
- }
- .var numberList = List()
- .for (var i = 0; i < 200; i++) {
- .eval numberList.add(i)
- }
- .var shuffleNumberList = numberList.shuffle()
- Random200Numbers:
- .for (var i = 0; i < 200; i++) {
- .byte shuffleNumberList.get(i)
- }
- Random200Numbers_Active: .byte 0
- Random200Numbers_Counter: .byte 0
- // e000: bitmap copy routine data. Used to create reference tables to identify the bitmap & screen address to copy
- Copy_Bitmap_X_Table_Hi: .fill 40, >floor(i*8)
- Copy_Bitmap_X_Table_Lo: .fill 40, <floor(i*8)
- Copy_Bitmap_Y_Table_Hi: .fill 200, >$e000+[320*floor(i/8)]+[i&7]
- Copy_Bitmap_Y_Table_Lo: .fill 200, <$e000+[320*floor(i/8)]+[i&7]
- // Logo: bitmap copy routine data. Used to create reference tables to identify the bitmap & screen address to copy
- Copy_Logo_X_Table_Hi: .fill 40, >floor(i*8)
- Copy_Logo_X_Table_Lo: .fill 40, <floor(i*8)
- Copy_Logo_Y_Table_Hi: .fill 200, >$a000+[320*floor(i/8)]+[i&7]
- Copy_Logo_Y_Table_Lo: .fill 200, <$a000+[320*floor(i/8)]+[i&7]
- // IRQ Setup
- irq_part2_0: {
- irq_start(end)
- irq_end(irq_part2_1, part_2_textmodeswitchline)
- end:
- rti
- }
- irq_part2_1: {
- irq_start(end)
- irq_end(irq_part2_2, part_2_rastercolorline)
- end:
- }
- // Stable raster IRQ for color bars
- irq_part2_2: {
- double_irq(end, irq_part2_3)
- irq_part2_3:
- irq_end(irq_part2_0, part_2_irq0line)
- end:
- }
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- // DATA
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- // -------------------------------------------------
- // Demo part
- // -------------------------------------------------
- active_demo_part: .byte 0 // This is a variable that counts up from 0 the parts in the demo.
- // used for the 16 bit addition & subtraction routines
- num1lo: .byte 0
- num1hi: .byte 0
- num2lo: .byte 0
- num2hi: .byte 0
- resultlo: .byte 0
- resulthi: .byte 0
- // -------------------------------------------------
- // GFX
- // -------------------------------------------------
- //Colors: .fill bitmap_colors.getSize(), bitmap_colors.get(i)
- //Bitmap: .fill bitmap_bitmap.getSize(), bitmap_bitmap.get(i)
- // -------------------------------------------------
- // Double screen buffer flag
- // -------------------------------------------------
- switch_flag: .byte 1 // starts from 2
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- // SUBS
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- init_data_variables: {
- lda #%00000010
- sta active_demo_part // which demo part is active - starting on part 1
- lda #1
- sta switch_flag // initialize flag for double-buffering
- rts
- }
- // ========================================================================
- // Description: 16 bit addtion
- //
- // Input: Two 16-bit unsigned values in
- // num1lo:
- // num1hi:
- // num2lo:
- // num2hi:
- // Output: 16-bit unsigned value in PRODUCT
- // resultlo:
- // resulthi:
- add_16_bit: {
- clc // clear carry
- lda num1lo
- adc num2lo
- sta resultlo // store sum of LSBs
- lda num1hi
- adc num2hi // add the MSBs using carry from
- sta resulthi // the previous calculation
- rts
- }
- //====================================================================================
- // Time Delay 1
- //
- // This subroutine can be used to generate time delays between 26 microseconds and
- // 329 milliseconds, with a resolution of 5 microseconds. The contents of locations
- // $20 and $21 select the duration of the time delay.
- //
- // A calue of one in $20 and $21 generates the minimum time delay, 26 microseconds.
- // Each additional increment in location $20 generates a 5 microsecond time delay.
- // Each additonal increment in location $21 generates a 1284 microsecond time delay.
- //
- // Page 85 in 6502 Application Design (URL: https://mirror.thelifeofkenneth.com/sites/remotecpu.com/Commodore/Reference%20Material/Books/General%20Programming%20Books/6502%20Software%20Design.pdf )
- //
- //====================================================================================
- time_delay_1: {
- // lets preserve the registers
- pha
- txa
- pha
- tya
- pha
- ldx $20 // load x with 5 micro second count
- ldy #10 // load y with 1284 micro count
- wait:
- dex
- bne wait // loop until x is zero
- dey
- bne wait // loop until both x & y are zero
- // lets restore the registers
- pla
- tay
- pla
- tax
- pla
- rts
- }
- // Clear secondary bitmap screen buffer - partial only - bottom of screen with vector text
- ClearBitmapBuffer2_partial_bottom: {
- ldx #$00
- lda #$00
- // clear out bitmap
- !loop:
- // sta bitmap_address_3,x
- // sta (bitmap_address_3 + $100),x
- // sta (bitmap_address_3 + $200),x
- // sta (bitmap_address_3 + $300),x
- // sta (bitmap_address_3 + $400),x
- // sta (bitmap_address_3 + $500),x
- // sta (bitmap_address_3 + $600),x
- // sta (bitmap_address_3 + $700),x
- // sta (bitmap_address_3 + $800),x
- // sta (bitmap_address_3 + $900),x
- // sta (bitmap_address_3 + $a00),x
- // sta (bitmap_address_3 + $b00),x
- // sta (bitmap_address_3 + $c00),x
- // sta (bitmap_address_3 + $d00),x
- // sta (bitmap_address_3 + $e00),x
- // sta (bitmap_address_3 + $f00),x
- // sta (bitmap_address_3 + $1000),x
- // sta (bitmap_address_3 + $1100),x
- // sta (bitmap_address_3 + $1200),x
- // sta (bitmap_address_3 + $1300),x
- // sta (bitmap_address_3 + $1400),x
- // sta (bitmap_address_3 + $1500),x
- sta (bitmap_address_3 + $1600),x
- sta (bitmap_address_3 + $1700),x
- sta (bitmap_address_3 + $1800),x
- sta (bitmap_address_3 + $1900),x
- sta (bitmap_address_3 + $1a00),x
- sta (bitmap_address_3 + $1b00),x
- sta (bitmap_address_3 + $1c00),x
- sta (bitmap_address_3 + $1d00),x
- // sta (bitmap_address_3 + $1e00),x
- // sta (bitmap_address_3 + $1ef9),x
- dex
- bne !loop-
- ldx #$39
- lda #$f0
- // clear out screen memory - have to set the pen color so the vectors are seen
- color_memory:
- // sta screen_memory_3,x
- // sta (screen_memory_3 + 39 ),x
- // sta (screen_memory_3 + 78 ),x
- // sta (screen_memory_3 + 117 ),x
- // sta (screen_memory_3 + 156 ),x
- // sta (screen_memory_3 + 195 ),x
- // sta (screen_memory_3 + 234 ),x
- // sta (screen_memory_3 + 273 ),x
- // sta (screen_memory_3 + 312 ),x
- // sta (screen_memory_3 + 351 ),x
- // sta (screen_memory_3 + 390 ),x
- // sta (screen_memory_3 + 429 ),x
- // sta (screen_memory_3 + 468 ),x
- // sta (screen_memory_3 + 507 ),x
- // sta (screen_memory_3 + 546 ),x
- // sta (screen_memory_3 + 585 ),x
- // sta (screen_memory_3 + 624 ),x
- sta (screen_memory_3 + 663 ),x
- sta (screen_memory_3 + 702 ),x
- sta (screen_memory_3 + 741 ),x
- sta (screen_memory_3 + 780 ),x
- sta (screen_memory_3 + 819 ),x
- sta (screen_memory_3 + 858 ),x
- sta (screen_memory_3 + 897 ),x
- sta (screen_memory_3 + 936 ),x
- dex
- bne color_memory
- rts
- }
- // Clear primary bitmap screen buffer - partial only - bottom of screen with vector text
- ClearBitmapBuffer1_partial_bottom: {
- ldx #$00
- lda #$00
- !loop:
- // sta bitmap_address_2,x
- // sta (bitmap_address_2 + $100),x
- // sta (bitmap_address_2 + $200),x
- // sta (bitmap_address_2 + $300),x
- // sta (bitmap_address_2 + $400),x
- // sta (bitmap_address_2 + $500),x
- // sta (bitmap_address_2 + $600),x
- // sta (bitmap_address_2 + $700),x
- // sta (bitmap_address_2 + $800),x
- // sta (bitmap_address_2 + $900),x
- // sta (bitmap_address_2 + $a00),x
- // sta (bitmap_address_2 + $b00),x
- // sta (bitmap_address_2 + $c00),x
- // sta (bitmap_address_2 + $d00),x
- // sta (bitmap_address_2 + $e00),x
- // sta (bitmap_address_2 + $f00),x
- // sta (bitmap_address_2 + $1000),x
- // sta (bitmap_address_2 + $1100),x
- // sta (bitmap_address_2 + $1200),x
- // sta (bitmap_address_2 + $1300),x
- // sta (bitmap_address_2 + $1400),x
- // sta (bitmap_address_2 + $1500),x
- sta (bitmap_address_2 + $1600),x
- sta (bitmap_address_2 + $1700),x
- sta (bitmap_address_2 + $1800),x
- sta (bitmap_address_2 + $1900),x
- sta (bitmap_address_2 + $1a00),x
- sta (bitmap_address_2 + $1b00),x
- sta (bitmap_address_2 + $1c00),x
- sta (bitmap_address_2 + $1d00),x
- // sta (bitmap_address_2 + $1e00),x
- // sta (bitmap_address_2 + $1f00),x
- dex
- bne !loop-
- ldx #$39
- lda #$f0
- // clear out screen memory - have to set the pen color so the vectors are seen
- color_memory:
- // sta screen_memory_2,x
- // sta (screen_memory_2 + 39 ),x
- // sta (screen_memory_2 + 78 ),x
- // sta (screen_memory_2 + 117 ),x
- // sta (screen_memory_2 + 156 ),x
- // sta (screen_memory_2 + 195 ),x
- // sta (screen_memory_2 + 234 ),x
- // sta (screen_memory_2 + 273 ),x
- // sta (screen_memory_2 + 312 ),x
- // sta (screen_memory_2 + 351 ),x
- // sta (screen_memory_2 + 390 ),x
- // sta (screen_memory_2 + 429 ),x
- // sta (screen_memory_2 + 468 ),x
- // sta (screen_memory_2 + 507 ),x
- // sta (screen_memory_2 + 546 ),x
- // sta (screen_memory_2 + 585 ),x
- // sta (screen_memory_2 + 624 ),x
- sta (screen_memory_2 + 663 ),x
- sta (screen_memory_2 + 702 ),x
- sta (screen_memory_2 + 741 ),x
- sta (screen_memory_2 + 780 ),x
- sta (screen_memory_2 + 819 ),x
- sta (screen_memory_2 + 858 ),x
- sta (screen_memory_2 + 897 ),x
- sta (screen_memory_2 + 936 ),x
- dex
- bne color_memory
- rts
- }
- //============================
- // Pref mem
- //============================
- pref_mem: {
- raster2:
- lda $d011 // read screen control register #1.
- bpl raster2
- SwitchVICBank(vic_bank_2)
- SetScreenMemory(screen_memory_2 - vic_base_2)
- SetBitmapAddress(bitmap_address_2 - vic_base_2)
- rts
- }
- //====================================================================================
- // Alt mem: bitmap memory from 24576, screen memory from 23552
- //====================================================================================
- alt_mem: {
- raster1:
- lda $d011 // read screen control register #1
- bpl raster1
- SwitchVICBank(vic_bank_3)
- SetScreenMemory(screen_memory_3 - vic_base_3)
- SetBitmapAddress(bitmap_address_3 - vic_base_3)
- rts
- }
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- // MACROS
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- //
- // Switch bank in VIC-II
- //
- // Args:
- // bank: bank number to switch to. Valid values: 0-3.
- //
- .macro SwitchVICBank(bank) {
- //
- // The VIC-II chip can only access 16K bytes at a time. In order to
- // have it access all of the 64K available, we have to tell it to look
- // at one of four banks.
- //
- // This is controlled by bits 0 and 1 in $dd00 (PORT A of CIA #2).
- //
- // +------+-------+----------+-------------------------------------+
- // | BITS | BANK | STARTING | VIC-II CHIP RANGE |
- // | | | LOCATION | |
- // +------+-------+----------+-------------------------------------+
- // | 00 | 3 | 49152 | ($C000-$FFFF)* |
- // | 01 | 2 | 32768 | ($8000-$BFFF) |
- // | 10 | 1 | 16384 | ($4000-$7FFF)* |
- // | 11 | 0 | 0 | ($0000-$3FFF) (DEFAULT VALUE) |
- // +------+-------+----------+-------------------------------------+
- .var bits=%11
- .if (bank==0) .eval bits=%11
- .if (bank==1) .eval bits=%10
- .if (bank==2) .eval bits=%01
- .if (bank==3) .eval bits=%00
- .print "bits=%" + toBinaryString(bits)
- //
- // Set Data Direction for CIA #2, Port A to output
- //
- lda $dd02
- and #%11111100 // Mask the bits we're interested in.
- ora #$03 // Set bits 0 and 1.
- sta $dd02
- //
- // Tell VIC-II to switch to bank
- //
- lda $dd00
- and #%11111100
- ora #bits
- sta $dd00
- }
- //
- // Enter hires bitmap mode (a.k.a. standard bitmap mode)
- //
- .macro SetHiresBitmapMode() {
- //
- // Clear extended color mode (bit 6) and set bitmap mode (bit 5)
- //
- lda $d011
- and #%10111111
- ora #%00100000
- sta $d011
- //
- // Clear multi color mode (bit 4)
- //
- lda $d016
- and #%11101111
- sta $d016
- }
- //
- // Switch location of screen memory.
- //
- // Args:
- // address: Address relative to current VIC-II bank base address.
- // Valid values: $0000-$3c00. Must be a multiple of $0400.
- //
- .macro SetScreenMemory(address) {
- //
- // The most significant nibble of $D018 selects where the screen is
- // located in the current VIC-II bank.
- //
- // +------------+-----------------------------+
- // | | LOCATION* |
- // | BITS +---------+-------------------+
- // | | DECIMAL | HEX |
- // +------------+---------+-------------------+
- // | 0000XXXX | 0 | $0000 |
- // | 0001XXXX | 1024 | $0400 (DEFAULT) |
- // | 0010XXXX | 2048 | $0800 |
- // | 0011XXXX | 3072 | $0C00 |
- // | 0100XXXX | 4096 | $1000 |
- // | 0101XXXX | 5120 | $1400 |
- // | 0110XXXX | 6144 | $1800 |
- // | 0111XXXX | 7168 | $1C00 |
- // | 1000XXXX | 8192 | $2000 |
- // | 1001XXXX | 9216 | $2400 |
- // | 1010XXXX | 10240 | $2800 |
- // | 1011XXXX | 11264 | $2C00 |
- // | 1100XXXX | 12288 | $3000 |
- // | 1101XXXX | 13312 | $3400 |
- // | 1110XXXX | 14336 | $3800 |
- // | 1111XXXX | 15360 | $3C00 |
- // +------------+---------+-------------------+
- //
- .var bits = (address / $0400) << 4
- lda $d018
- and #%00001111
- ora #bits
- sta $d018
- }
- //
- // Set location of bitmap.
- //
- // Args:
- // address: Address relative to VIC-II bank address.
- // Valid values: $0000 (bitmap at $0000-$1FFF)
- // $2000 (bitmap at $2000-$3FFF)
- //
- .macro SetBitmapAddress(address) {
- //
- // In standard bitmap mode the location of the bitmap area can
- // be set to either BANK address + $0000 or BANK address + $2000
- //
- // By setting bit 3, we can configure which of the locations to use.
- //
- .var bits=0
- lda $d018
- .if (address == $0000) { // this is chosen > bitmap address =
- and #%11110111
- }
- .if (address == $2000) {
- ora #%00001000
- }
- .if (address == $0c00) {
- lda #%00111000
- }
- sta $d018
- }
- .macro ResetStandardBitMapMode() {
- lda $d011
- and #%11011111
- sta $d011
- }
- // This is the code that goes in at the top before the code that is required is executed
- .macro SwitchScreenBufferTop() {
- // lda switch_flag
- // bne use_screen2
- // // clear first buffer (if required)
- // // <CODE GOES IN HERE>
- // jsr ClearBitmapBuffer1
- // jmp skip_use_screen2 // switch from buffer2 to buffer1
- //use_screen2:
- // // clear second buffer (if required)
- // // <CODE GOES IN HERE>
- // jsr ClearBitmapBuffer2
- //skip_use_screen2:
- // Need to figure out which screen buffer we are going to clear; e.g. the one that is not visible
- lda switch_flag
- bne use_screen2_clear_bitmap // if switch_flag = 1 then clear secondary screen buffer. We are drawing to primary
- jsr ClearBitmapBuffer2_partial_bottom
- jmp finished_clearing_bitmaps
- use_screen2_clear_bitmap:
- jsr ClearBitmapBuffer1_partial_bottom
- finished_clearing_bitmaps:
- }
- // This is the code that goes in at the bottom after the code that is required is executed
- .macro SwitchScreenBufferBottom() {
- // Time to switch buffers again as we are dooooone!
- lda switch_flag
- bne secondary_screen_buffer_active
- jsr alt_mem
- jmp skip_alt_mem
- secondary_screen_buffer_active:
- jsr pref_mem
- skip_alt_mem:
- lda switch_flag
- eor #$01
- sta switch_flag // switchs flag for double buffering
- }
- .macro FillBitmap(addr, value) {
- ldx #$00
- lda #value
- !loop:
- sta addr,x
- sta (addr + $100),x
- sta (addr + $200),x
- sta (addr + $300),x
- sta (addr + $400),x
- sta (addr + $500),x
- sta (addr + $600),x
- sta (addr + $700),x
- sta (addr + $800),x
- sta (addr + $900),x
- sta (addr + $a00),x
- sta (addr + $b00),x
- sta (addr + $c00),x
- sta (addr + $d00),x
- sta (addr + $e00),x
- sta (addr + $f00),x
- sta (addr + $1000),x
- sta (addr + $1100),x
- sta (addr + $1200),x
- sta (addr + $1300),x
- sta (addr + $1400),x
- sta (addr + $1500),x
- sta (addr + $1600),x
- sta (addr + $1700),x
- sta (addr + $1800),x
- sta (addr + $1900),x
- sta (addr + $1a00),x
- sta (addr + $1b00),x
- sta (addr + $1c00),x
- sta (addr + $1d00),x
- sta (addr + $1e00),x
- sta (addr + $1f00),x
- dex
- bne !loop-
- }
- //
- // Fill screen memory with a value.
- //
- // Args:
- // address: Absolute base address of screen memory.
- // value: byte value to fill screen memory with
- //
- .macro FillScreenMemory(address, value) {
- //
- // Screen memory is 40 * 25 = 1000 bytes ($3E8 bytes)
- //
- ldx #$00
- lda #value
- // fill the first 255*3=765 bytes
- !loop:
- sta address,x
- sta (address + $100),x
- sta (address + $200),x
- dex
- bne !loop-
- // fill the last 232 bytes; e.g.
- ldx #$e8
- !loop:
- sta (address + $2ff),x // Start one byte below the area we're clearing
- // That way we can bail directly when zero without an additional comparison
- dex
- bne !loop-
- }
- .macro CopyBitmap(sourceaddr, destaddr) {
- ldx #$00
- copy_bitmap_loop:
- lda sourceaddr,x
- sta destaddr,x
- lda (sourceaddr + $100),x
- sta (destaddr + $100),x
- lda (sourceaddr + $200),x
- sta (destaddr + $200),x
- lda (sourceaddr + $300),x
- sta (destaddr + $300),x
- lda (sourceaddr + $400),x
- sta (destaddr + $400),x
- lda (sourceaddr + $500),x
- sta (destaddr + $500),x
- lda (sourceaddr + $600),x
- sta (destaddr + $600),x
- lda (sourceaddr + $700),x
- sta (destaddr + $700),x
- lda (sourceaddr + $800),x
- sta (destaddr + $800),x
- lda (sourceaddr + $900),x
- sta (destaddr + $900),x
- lda (sourceaddr + $a00),x
- sta (destaddr + $a00),x
- lda (sourceaddr + $b00),x
- sta (destaddr + $b00),x
- lda (sourceaddr + $c00),x
- sta (destaddr + $c00),x
- lda (sourceaddr + $d00),x
- sta (destaddr + $d00),x
- lda (sourceaddr + $e00),x
- sta (destaddr + $e00),x
- lda (sourceaddr + $f00),x
- sta (destaddr + $f00),x
- lda (sourceaddr + $1000),x
- sta (destaddr + $1000),x
- lda (sourceaddr + $1100),x
- sta (destaddr + $1100),x
- lda (sourceaddr + $1200),x
- sta (destaddr + $1200),x
- lda (sourceaddr + $1300),x
- sta (destaddr + $1300),x
- lda (sourceaddr + $1400),x
- sta (destaddr + $1400),x
- lda (sourceaddr + $1500),x
- sta (destaddr + $1500),x
- lda (sourceaddr + $1600),x
- sta (destaddr + $1600),x
- lda (sourceaddr + $1700),x
- sta (destaddr + $1700),x
- lda (sourceaddr + $1800),x
- sta (destaddr + $1800),x
- lda (sourceaddr + $1900),x
- sta (destaddr + $1900),x
- lda (sourceaddr + $1a00),x
- sta (destaddr + $1a00),x
- lda (sourceaddr + $1b00),x
- sta (destaddr + $1b00),x
- lda (sourceaddr + $1c00),x
- sta (destaddr + $1c00),x
- lda (sourceaddr + $1d00),x
- sta (destaddr + $1d00),x
- lda (sourceaddr + $1e00),x
- sta (destaddr + $1e00),x
- lda (sourceaddr + $1f00),x
- sta (destaddr + $1f00),x
- dex
- txa
- cmp #0
- beq done
- jmp copy_bitmap_loop
- done:
- //bne copy_bitmap_loop
- }
- //
- // Copy screen memory with a value. Used typically to copy color scheme for bitmap
- //
- // Args:
- // sourceaddress: Absolute base address of screen memory.
- // sourceaddress: Absolute base address of screen memory.
- //
- .macro CopyScreenMemory(sourceaddr, destaddr) {
- //
- // Screen memory is 40 * 25 = 1000 bytes ($3E8 bytes)
- //
- ldx #$00
- copy_loop_1:
- lda sourceaddr,x
- sta destaddr,x
- lda (sourceaddr + $100),x
- sta (destaddr + $100),x
- lda (sourceaddr + $200),x
- sta (destaddr + $200),x
- dex
- bne copy_loop_1
- ldx #$e8
- copy_loop_2:
- lda (sourceaddr + $2ff),x // Start one byte below the area we're clearing
- sta (destaddr + $2ff),x // Start one byte below the area we're clearing
- // That way we can bail directly when zero without an additional comparison
- dex
- bne copy_loop_2
- }
- .macro SetupIRQ(IRQaddr,IRQline,IRQlineHi) {
- lda #$7f // Disable CIA IRQ's
- sta $dc0d
- sta $dd0d
- lda #<IRQaddr // Install RASTER IRQ
- ldx #>IRQaddr // into Hardware
- sta $fffe // Interrupt Vector
- stx $ffff
- lda #$01 // Enable RASTER IRQs
- sta $d01a
- lda #IRQline // IRQ raster line
- sta $d012
- .if (IRQline > 255) {
- .error "supports only less than 256 lines"
- }
- lda $d011 // clear IRQ raster line bit 8
- and #$7f
- sta $d011
- asl $d019 // Ack any previous raster interrupt
- bit $dc0d // reading the interrupt control registers
- bit $dd0d // clears them
- }
- //----------------------------------------------------------
- .macro EndIRQ(nextIRQaddr,nextIRQline,IRQlineHi) {
- asl $d019
- lda #<nextIRQaddr
- sta $fffe
- lda #>nextIRQaddr
- sta $ffff
- lda #nextIRQline
- sta $d012
- .if(IRQlineHi) {
- lda $d011
- ora #$80
- sta $d011
- }
- }
- .macro irq_start(end_lbl) {
- sta end_lbl-6
- stx end_lbl-4
- sty end_lbl-2
- }
- .macro irq_end(next, line) {
- EndRasterIRQ(next, line, false)
- lda #$00
- ldx #$00
- ldy #$00
- rti
- }
- // Setup stable raster IRQ NOTE: cannot be set on a badline or the second
- // interrupt happens before we store the stack pointer (among other things)
- .macro double_irq(end, stableIRQ) {
- //The CPU cycles spent to get in here [7]
- irq_start(end) // 4+4+4 cycles
- lda #<stableIRQ // Set IRQ Vector [4]
- ldx #>stableIRQ // to point to the [4]
- // next part of the
- sta $fffe // Stable IRQ [4]
- stx $ffff // [4]
- inc $d012 // set raster interrupt to the next line [6]
- asl $d019 // Ack raster interrupt [6]
- tsx // Store the stack pointer! [2]
- cli // [2]
- // Total spent cycles up to this point [51]
- nop // [53]
- nop // [55]
- nop // [57]
- nop // [59]
- nop //Execute nop's [61]
- nop //until next RASTER [63]
- nop //IRQ Triggers
- }
- //----------------------------------------------------------
- // Sample source call: SetupIRQ(irq_part1_0, irq0line, false)
- //----------------------------------------------------------
- .macro SetupRasterIRQ(IRQaddr,IRQline,IRQlineHi) {
- lda #$7f // Disable CIA IRQ's
- sta $dc0d
- sta $dd0d
- lda #<IRQaddr // Install RASTER IRQ
- ldx #>IRQaddr // into Hardware
- sta $fffe // Interrupt Vector
- stx $ffff
- lda #$01 // Enable RASTER IRQs
- sta $d01a
- lda #IRQline // IRQ raster line
- sta $d012
- .if (IRQline > 255) {
- .error "supports only less than 256 lines"
- }
- lda $d011 // clear IRQ raster line bit 8
- and #$7f
- sta $d011
- asl $d019 // Ack any previous raster interrupt
- bit $dc0d // reading the interrupt control registers
- bit $dd0d // clears them
- }
- //----------------------------------------------------------
- .macro EndRasterIRQ(nextIRQaddr,nextIRQline,IRQlineHi) {
- asl $d019
- lda #<nextIRQaddr
- sta $fffe
- lda #>nextIRQaddr
- sta $ffff
- lda #nextIRQline
- sta $d012
- .if(IRQlineHi) {
- lda $d011
- ora #$80
- sta $d011
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement