Advertisement
jskogsta

Gradual line by line fill problem

Sep 1st, 2019
2,182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // This is a test for a line by line fill / copy routine. Intention was to gradually copy in a gfx
  2. // from buffer 1 (not visible) to buffer 2 (vibisble). For some reason the copy does not start on the
  3. // first pixel/byte on every line.
  4. //
  5. // The lines are "randomised" over the 200 lines in the hires display.
  6. //
  7. // Rather than go pixel by pixel, I was going to copy a full byte in the x direction to set 8 pixels
  8. // in one go. That seems to work, but.. there's something else going on...
  9.  
  10. .var vic_bank_2=2                           // vic bank 2 = 32768 ($8000-$BFFF)
  11. .var vic_base_2=$4000*vic_bank_2                // a VIC-II bank indicates a 16K region
  12. .var screen_memory_2=$0c00 + vic_base_2         // screen memory = 3072 + 32768 = 35840 (0x8c00)
  13. .var bitmap_address_2=$2000 + vic_base_2        // bitmap address = 40960 (0xa000)
  14. .var text_mode_screen_memory_2=vic_base_2       // text memory = $8000. Charset in $1000 which is in bank 2 mapped to character rom
  15.  
  16. .var vic_bank_3=3
  17. .var vic_base_3=$4000*vic_bank_3
  18. .var screen_memory_3=$0c00 + vic_base_3
  19. .var bitmap_address_3=$2000 + vic_base_3
  20. .var text_mode_screen_memory_3=vic_base_3
  21. // The bitmap pointer has to reside in zero page because of the indirect addressing mode used. Screen buffer #1.
  22. .const bitmap_pointer = $32
  23. .const screen_color_pointer = $34
  24.  
  25. // IRQ Interupt setup
  26. .const part_1_irq0line = 30
  27. .const part_1_irq1line = 245
  28. .const part_1_irq2line = 246
  29. .const part_2_irq0line = 16
  30. .const part_2_textmodeswitchline = 17
  31. .const part_2_rastercolorline = 18
  32.  
  33. // Screen & border registers
  34. .label border_color = $d020
  35. .label screen_color = $d021
  36. // ZERO PAGE VARIABLE : These are pointers used for the
  37. .const ScreenBuffer2_part1_lo=$32
  38. .const ScreenBuffer2_part1_hi=$33
  39. .const ScreenBuffer2_part2_lo=$34
  40. .const ScreenBuffer2_part2_hi=$35
  41.  
  42. .const BitmapBuffer2_part1_lo=$36
  43. .const BitmapBuffer2_part1_hi=$37
  44. .const BitmapBuffer2_part2_lo=$38
  45. .const BitmapBuffer2_part2_hi=$39
  46.  
  47.  
  48. .const ScreenColorBuffer2_part1_lo=$4a
  49. .const ScreenColorBuffer2_part1_hi=$4b
  50. .const ScreenColorBuffer2_part2_lo=$4c
  51. .const ScreenColorBuffer2_part2_hi=$4d
  52. .const BitmapColorBuffer2_part1_lo=$4e
  53. .const BitmapColorBuffer2_part1_hi=$4f
  54. .const BitmapColorBuffer2_part2_lo=$50
  55. .const BitmapColorBuffer2_part2_hi=$51
  56.  
  57. // Gradually display logo routine - ZP pointers used to gradually display the logo in screen buffer
  58. .const Copy_Logo_Y_Lo=$52
  59. .const Copy_Logo_Y_Hi=$53
  60. .const Copy_Logo_X_Lo=$54
  61. .const Copy_Logo_X_Hi=$55
  62.  
  63. .const Copy_Logo_Colors_Y_Lo=$52
  64. .const Copy_Logo_Colors_Y_Hi=$53
  65. .const Copy_Logo_Colors_X_Lo=$54
  66. .const Copy_Logo_Colors_X_Hi=$55
  67.  
  68.  
  69. .const Copy_Bitmap_Y_Lo=$56
  70. .const Copy_Bitmap_Y_Hi=$57
  71. .const Copy_Bitmap_X_Lo=$58
  72. .const Copy_Bitmap_X_Hi=$59
  73.  
  74. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  75. //  MAIN CODE
  76. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  77.  
  78. BasicUpstart2(start)
  79.  
  80. start:    
  81.     jsr init_data_variables
  82.  
  83.  
  84. main_loop:
  85.  
  86.     lda #%00000010
  87.     eor active_demo_part
  88.     and #%00000010
  89.     beq demo_part_2
  90.     jmp check_demo_part_end
  91. demo_part_2:
  92.     // Demo part #2 - code here
  93.     jsr demo_section_part_2
  94.     jmp check_demo_part_end
  95. check_demo_part_end:
  96.     jmp main_loop
  97.  
  98.  
  99. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  100. //  PART 2
  101. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  102.  
  103. demo_section_part_2: {
  104.  
  105.     SwitchVICBank(vic_bank_3)
  106.     SetHiresBitmapMode()
  107.     SetScreenMemory(screen_memory_3 - vic_base_3)
  108.     SetBitmapAddress(bitmap_address_3 - vic_base_3)
  109.  
  110.     // Clear out both screen & color buffers
  111.     FillBitmap(bitmap_address_2, $00)
  112.     FillScreenMemory(screen_memory_2, $f0)
  113.     FillBitmap(bitmap_address_3, $00)
  114.     FillScreenMemory(screen_memory_3, $f0)
  115.  
  116.     lda #BLACK
  117.     sta border_color
  118.     sta screen_color
  119.  
  120.     // IRQ setup - part 2
  121.     sei
  122.     // This causes the CPU to see RAM instead of KERNAL and
  123.     // BASIC ROM at $E000-$FFFF and $A000-$BFFF respectively.
  124.     //
  125.     // This causes the CPU to see RAM everywhere except for
  126.     // $D000-$E000, where the VIC-II, SID, CIA's etc are located.
  127.     lda #$35
  128.     sta $01
  129.     // Setup raster IRQ
  130.     SetupIRQ(irq_part2_0, part_2_irq0line, false)
  131.     cli
  132.  
  133.     ldy #0
  134.     sty Random200Numbers_Active                     // store the active line number that the sub routine will pick up and use to copy the logo line
  135.  
  136. copy_another_line:
  137.  
  138.     // 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)
  139.     ldy Random200Numbers_Active
  140.  
  141.     // lets use the reference number to pick the actual line number that we will copy next.. this list is randomized on every compile
  142.     lda Random200Numbers,y
  143.     tay
  144.  
  145.     // Source: Set up the ZP reference for the DZ logo which resides in memory somewhere
  146.     lda Copy_Logo_Y_Table_Lo,y
  147.     sta Copy_Logo_Y_Lo
  148.     lda Copy_Logo_Y_Table_Hi,y
  149.     sta Copy_Logo_Y_Hi
  150.  
  151.     // Destination: Set up the ZP reference for the current screen buffer that is displayed
  152.     lda Copy_Bitmap_Y_Table_Lo,y
  153.     sta Copy_Bitmap_Y_Lo
  154.     lda Copy_Bitmap_Y_Table_Hi,y
  155.     sta Copy_Bitmap_Y_Hi
  156.  
  157.     // We are copying 40 bytes across the x-axis - hence lets set x=40 and dex to zero and test
  158.     ldx #0
  159.  
  160. copy_more_line_bytes:
  161.  
  162.     // 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.
  163.     // 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
  164.     // need to use to find the right byte in the buffer ..
  165.     //.const Copy_Logo_X_Lo=$54
  166.     //.const Copy_Logo_X_Hi=$55
  167.     //.const Copy_Bitmap_X_Lo=$58
  168.     //.const Copy_Bitmap_X_Hi=$59
  169.  
  170.     ldy Copy_Bitmap_X_Table_Lo,x
  171.     sty num1lo
  172.     ldy Copy_Bitmap_X_Table_Hi,x
  173.     sty num1hi
  174.     ldy Copy_Bitmap_Y_Lo
  175.     sty num2lo
  176.     ldy Copy_Bitmap_Y_Hi
  177.     sty num2hi
  178.     jsr add_16_bit
  179.     ldy resultlo
  180.     sty Copy_Bitmap_X_Lo
  181.     ldy resulthi
  182.     sty Copy_Bitmap_X_Hi
  183.  
  184.     ldy Copy_Logo_X_Table_Lo,x
  185.     sty num1lo
  186.     ldy Copy_Logo_X_Table_Hi,x
  187.     sty num1hi
  188.     ldy Copy_Logo_Y_Lo
  189.     sty num2lo
  190.     ldy Copy_Logo_Y_Hi
  191.     sty num2hi
  192.     jsr add_16_bit
  193.     ldy resultlo
  194.     sty Copy_Logo_X_Lo
  195.     ldy resulthi
  196.     sty Copy_Logo_X_Hi
  197.     // we now have both the logo and bitmap pointers updated for the current X value and we can proceed with copying the byte
  198.  
  199.     // we need to put in a delay here, or else it will transition in too fast..
  200.     jsr time_delay_1
  201.  
  202.     // 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
  203.     lda #%11111111
  204.     sta (Copy_Bitmap_X_Lo),y
  205.  
  206.     // 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
  207.     inx
  208.     cpx #40
  209.     bne copy_more_line_bytes
  210.  
  211.     // we need to put in a delay here, or else it will transition in too fast..
  212.     jsr time_delay_1
  213.  
  214.     inc Random200Numbers_Active
  215.     ldx Random200Numbers_Active
  216.     cpx #200
  217.     bcc copy_another_line
  218.  
  219.     CopyBitmap(bitmap_address_3, bitmap_address_2)
  220.  
  221.     // set the switch to move on from this setup part to the next demo part
  222.     lda #%00000100
  223.     sta active_demo_part                    // which demo part is active - starting on part 1
  224.  
  225.     rts
  226. }
  227.  
  228. .var numberList = List()
  229. .for (var i = 0; i < 200; i++) {
  230.     .eval numberList.add(i)
  231. }
  232.  
  233. .var shuffleNumberList = numberList.shuffle()
  234.  
  235.  
  236. Random200Numbers:
  237.     .for (var i = 0; i < 200; i++) {
  238.         .byte shuffleNumberList.get(i)
  239.     }
  240. Random200Numbers_Active:    .byte 0
  241. Random200Numbers_Counter:   .byte 0
  242.  
  243. // e000: bitmap copy routine data. Used to create reference tables to identify the bitmap & screen address to copy
  244. Copy_Bitmap_X_Table_Hi: .fill 40, >floor(i*8)
  245. Copy_Bitmap_X_Table_Lo: .fill 40, <floor(i*8)
  246. Copy_Bitmap_Y_Table_Hi: .fill 200, >$e000+[320*floor(i/8)]+[i&7]
  247. Copy_Bitmap_Y_Table_Lo: .fill 200, <$e000+[320*floor(i/8)]+[i&7]
  248.  
  249. // Logo: bitmap copy routine data. Used to create reference tables to identify the bitmap & screen address to copy
  250. Copy_Logo_X_Table_Hi:       .fill 40, >floor(i*8)
  251. Copy_Logo_X_Table_Lo:       .fill 40, <floor(i*8)
  252. Copy_Logo_Y_Table_Hi:       .fill 200, >$a000+[320*floor(i/8)]+[i&7]
  253. Copy_Logo_Y_Table_Lo:       .fill 200, <$a000+[320*floor(i/8)]+[i&7]
  254.  
  255.  
  256. //  IRQ Setup
  257. irq_part2_0: {
  258.     irq_start(end)
  259.  
  260.  
  261.     irq_end(irq_part2_1, part_2_textmodeswitchline)
  262. end:
  263.     rti
  264. }
  265.  
  266. irq_part2_1: {
  267.     irq_start(end)
  268.  
  269.  
  270.     irq_end(irq_part2_2, part_2_rastercolorline)
  271. end:
  272. }
  273.  
  274. // Stable raster IRQ for color bars
  275. irq_part2_2: {
  276.     double_irq(end, irq_part2_3)
  277.  
  278. irq_part2_3:
  279.  
  280.  
  281.     irq_end(irq_part2_0, part_2_irq0line)
  282. end:
  283. }
  284.  
  285.  
  286. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  287. //  DATA
  288. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  289.  
  290. // -------------------------------------------------
  291. // Demo part
  292. // -------------------------------------------------
  293. active_demo_part:       .byte 0     // This is a variable that counts up from 0 the parts in the demo.
  294.  
  295. // used for the 16 bit addition & subtraction routines
  296. num1lo:                 .byte 0
  297. num1hi:                 .byte 0
  298. num2lo:                 .byte 0
  299. num2hi:                 .byte 0
  300. resultlo:               .byte 0
  301. resulthi:               .byte 0
  302.  
  303. // -------------------------------------------------
  304. // GFX
  305. // -------------------------------------------------
  306.  
  307. //Colors: .fill bitmap_colors.getSize(), bitmap_colors.get(i)
  308. //Bitmap: .fill bitmap_bitmap.getSize(), bitmap_bitmap.get(i)
  309.  
  310. // -------------------------------------------------
  311. // Double screen buffer flag
  312. // -------------------------------------------------
  313. switch_flag:    .byte 1         // starts from 2  
  314.  
  315.  
  316. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  317. //  SUBS
  318. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  319.  
  320.  
  321. init_data_variables: {
  322.  
  323.     lda #%00000010
  324.     sta active_demo_part                    // which demo part is active - starting on part 1
  325.  
  326.     lda #1
  327.     sta switch_flag                         // initialize flag for double-buffering
  328.  
  329.     rts
  330. }
  331.  
  332. // ========================================================================
  333. // Description: 16 bit addtion
  334. //                                                                        
  335. // Input: Two 16-bit unsigned values in
  336. //        num1lo:  
  337. //        num1hi:  
  338. //        num2lo:  
  339. //        num2hi:  
  340. // Output: 16-bit unsigned value in PRODUCT                              
  341. //        resultlo:
  342. //        resulthi:
  343. add_16_bit: {
  344.      clc                 // clear carry
  345.      lda num1lo
  346.      adc num2lo
  347.      sta resultlo        // store sum of LSBs
  348.      lda num1hi
  349.      adc num2hi          // add the MSBs using carry from
  350.      sta resulthi        // the previous calculation
  351.      rts
  352. }
  353.  
  354. //====================================================================================
  355. // Time Delay 1
  356. //
  357. // This subroutine can be used to generate time delays between 26 microseconds and
  358. // 329 milliseconds, with a resolution of 5 microseconds. The contents of locations
  359. // $20 and $21 select the duration of the time delay.
  360. //
  361. // A calue of one in $20 and $21 generates the minimum time delay, 26 microseconds.
  362. // Each additional increment in location $20 generates a 5 microsecond time delay.
  363. // Each additonal increment in location $21 generates a 1284 microsecond time delay.
  364. //
  365. // 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 )
  366. //
  367. //====================================================================================
  368.  
  369. time_delay_1: {
  370.     // lets preserve the registers
  371.     pha
  372.     txa
  373.     pha
  374.     tya
  375.     pha
  376.  
  377.     ldx $20         // load x with 5 micro second count
  378.     ldy #10         // load y with 1284 micro count
  379. wait:
  380.     dex
  381.     bne wait        // loop until x is zero
  382.     dey
  383.     bne wait        // loop until both x & y are zero
  384.  
  385.     // lets restore the registers
  386.     pla
  387.     tay
  388.     pla
  389.     tax
  390.     pla
  391.  
  392.     rts
  393. }
  394.  
  395. // Clear secondary bitmap screen buffer - partial only - bottom of screen with vector text
  396. ClearBitmapBuffer2_partial_bottom: {
  397.     ldx #$00
  398.     lda #$00
  399.     // clear out bitmap
  400. !loop:
  401. //    sta bitmap_address_3,x
  402. //    sta (bitmap_address_3 + $100),x
  403. //    sta (bitmap_address_3 + $200),x
  404. //    sta (bitmap_address_3 + $300),x
  405. //    sta (bitmap_address_3 + $400),x
  406. //    sta (bitmap_address_3 + $500),x
  407. //    sta (bitmap_address_3 + $600),x
  408. //    sta (bitmap_address_3 + $700),x
  409. //    sta (bitmap_address_3 + $800),x
  410. //    sta (bitmap_address_3 + $900),x
  411. //    sta (bitmap_address_3 + $a00),x
  412. //    sta (bitmap_address_3 + $b00),x
  413. //    sta (bitmap_address_3 + $c00),x
  414. //    sta (bitmap_address_3 + $d00),x
  415. //    sta (bitmap_address_3 + $e00),x
  416. //    sta (bitmap_address_3 + $f00),x
  417. //    sta (bitmap_address_3 + $1000),x
  418. //    sta (bitmap_address_3 + $1100),x
  419. //    sta (bitmap_address_3 + $1200),x
  420. //    sta (bitmap_address_3 + $1300),x
  421. //    sta (bitmap_address_3 + $1400),x
  422. //    sta (bitmap_address_3 + $1500),x
  423.     sta (bitmap_address_3 + $1600),x
  424.     sta (bitmap_address_3 + $1700),x
  425.     sta (bitmap_address_3 + $1800),x
  426.     sta (bitmap_address_3 + $1900),x
  427.     sta (bitmap_address_3 + $1a00),x
  428.     sta (bitmap_address_3 + $1b00),x
  429.     sta (bitmap_address_3 + $1c00),x
  430.     sta (bitmap_address_3 + $1d00),x
  431. //    sta (bitmap_address_3 + $1e00),x
  432. //    sta (bitmap_address_3 + $1ef9),x
  433.     dex
  434.     bne !loop-
  435.  
  436.     ldx #$39
  437.     lda #$f0
  438.     // clear out screen memory - have to set the pen color so the vectors are seen
  439. color_memory:
  440. //    sta screen_memory_3,x
  441. //    sta (screen_memory_3 + 39 ),x
  442. //    sta (screen_memory_3 + 78 ),x
  443. //    sta (screen_memory_3 + 117 ),x
  444. //    sta (screen_memory_3 + 156 ),x
  445. //    sta (screen_memory_3 + 195 ),x
  446. //    sta (screen_memory_3 + 234 ),x
  447. //    sta (screen_memory_3 + 273 ),x
  448. //    sta (screen_memory_3 + 312 ),x
  449. //    sta (screen_memory_3 + 351 ),x
  450. //    sta (screen_memory_3 + 390 ),x
  451. //    sta (screen_memory_3 + 429 ),x
  452. //    sta (screen_memory_3 + 468 ),x
  453. //    sta (screen_memory_3 + 507 ),x
  454. //    sta (screen_memory_3 + 546 ),x
  455. //    sta (screen_memory_3 + 585 ),x
  456. //    sta (screen_memory_3 + 624 ),x
  457.     sta (screen_memory_3 + 663 ),x
  458.     sta (screen_memory_3 + 702 ),x
  459.     sta (screen_memory_3 + 741 ),x
  460.     sta (screen_memory_3 + 780 ),x
  461.     sta (screen_memory_3 + 819 ),x
  462.     sta (screen_memory_3 + 858 ),x
  463.     sta (screen_memory_3 + 897 ),x
  464.     sta (screen_memory_3 + 936 ),x
  465.     dex
  466.     bne color_memory
  467.     rts
  468. }
  469.  
  470. // Clear primary bitmap screen buffer - partial only - bottom of screen with vector text
  471. ClearBitmapBuffer1_partial_bottom: {
  472.     ldx #$00
  473.     lda #$00
  474. !loop:
  475. //    sta bitmap_address_2,x
  476. //    sta (bitmap_address_2 + $100),x
  477. //    sta (bitmap_address_2 + $200),x
  478. //    sta (bitmap_address_2 + $300),x
  479. //    sta (bitmap_address_2 + $400),x
  480. //    sta (bitmap_address_2 + $500),x
  481. //    sta (bitmap_address_2 + $600),x
  482. //    sta (bitmap_address_2 + $700),x
  483. //    sta (bitmap_address_2 + $800),x
  484. //    sta (bitmap_address_2 + $900),x
  485. //    sta (bitmap_address_2 + $a00),x
  486. //    sta (bitmap_address_2 + $b00),x
  487. //    sta (bitmap_address_2 + $c00),x
  488. //    sta (bitmap_address_2 + $d00),x
  489. //    sta (bitmap_address_2 + $e00),x
  490. //    sta (bitmap_address_2 + $f00),x
  491. //    sta (bitmap_address_2 + $1000),x
  492. //    sta (bitmap_address_2 + $1100),x
  493. //    sta (bitmap_address_2 + $1200),x
  494. //    sta (bitmap_address_2 + $1300),x
  495. //    sta (bitmap_address_2 + $1400),x
  496. //    sta (bitmap_address_2 + $1500),x
  497.     sta (bitmap_address_2 + $1600),x
  498.     sta (bitmap_address_2 + $1700),x
  499.     sta (bitmap_address_2 + $1800),x
  500.     sta (bitmap_address_2 + $1900),x
  501.     sta (bitmap_address_2 + $1a00),x
  502.     sta (bitmap_address_2 + $1b00),x
  503.     sta (bitmap_address_2 + $1c00),x
  504.     sta (bitmap_address_2 + $1d00),x
  505. //    sta (bitmap_address_2 + $1e00),x
  506. //    sta (bitmap_address_2 + $1f00),x
  507.     dex
  508.     bne !loop-
  509.  
  510.     ldx #$39
  511.     lda #$f0
  512.     // clear out screen memory - have to set the pen color so the vectors are seen
  513. color_memory:
  514. //    sta screen_memory_2,x
  515. //    sta (screen_memory_2 + 39 ),x
  516. //    sta (screen_memory_2 + 78 ),x
  517. //    sta (screen_memory_2 + 117 ),x
  518. //    sta (screen_memory_2 + 156 ),x
  519. //    sta (screen_memory_2 + 195 ),x
  520. //    sta (screen_memory_2 + 234 ),x
  521. //    sta (screen_memory_2 + 273 ),x
  522. //    sta (screen_memory_2 + 312 ),x
  523. //    sta (screen_memory_2 + 351 ),x
  524. //    sta (screen_memory_2 + 390 ),x
  525. //    sta (screen_memory_2 + 429 ),x
  526. //    sta (screen_memory_2 + 468 ),x
  527. //    sta (screen_memory_2 + 507 ),x
  528. //    sta (screen_memory_2 + 546 ),x
  529. //    sta (screen_memory_2 + 585 ),x
  530. //    sta (screen_memory_2 + 624 ),x
  531.     sta (screen_memory_2 + 663 ),x
  532.     sta (screen_memory_2 + 702 ),x
  533.     sta (screen_memory_2 + 741 ),x
  534.     sta (screen_memory_2 + 780 ),x
  535.     sta (screen_memory_2 + 819 ),x
  536.     sta (screen_memory_2 + 858 ),x
  537.     sta (screen_memory_2 + 897 ),x
  538.     sta (screen_memory_2 + 936 ),x
  539.     dex
  540.     bne color_memory
  541.  
  542.  
  543.  
  544.     rts
  545. }
  546.  
  547. //============================
  548. // Pref mem
  549. //============================
  550. pref_mem: {
  551. raster2:
  552.      lda $d011                // read screen control register #1.
  553.      bpl raster2
  554.      SwitchVICBank(vic_bank_2)
  555.      SetScreenMemory(screen_memory_2 - vic_base_2)
  556.      SetBitmapAddress(bitmap_address_2 - vic_base_2)
  557.      rts
  558. }
  559.  
  560.  
  561. //====================================================================================
  562. // Alt mem: bitmap memory from 24576, screen memory from 23552
  563. //====================================================================================
  564. alt_mem: {
  565. raster1:
  566.      lda $d011                     // read screen control register #1
  567.      bpl raster1
  568.      SwitchVICBank(vic_bank_3)
  569.      SetScreenMemory(screen_memory_3 - vic_base_3)
  570.      SetBitmapAddress(bitmap_address_3 - vic_base_3)
  571.      rts
  572. }
  573.  
  574.  
  575. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  576. //  MACROS
  577. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  578.  
  579. //
  580. // Switch bank in VIC-II
  581. //
  582. // Args:
  583. //    bank: bank number to switch to. Valid values: 0-3.
  584. //
  585. .macro SwitchVICBank(bank) {
  586.     //
  587.     // The VIC-II chip can only access 16K bytes at a time. In order to
  588.     // have it access all of the 64K available, we have to tell it to look
  589.     // at one of four banks.
  590.     //
  591.     // This is controlled by bits 0 and 1 in $dd00 (PORT A of CIA #2).
  592.     //
  593.     //  +------+-------+----------+-------------------------------------+
  594.     //  | BITS |  BANK | STARTING |  VIC-II CHIP RANGE                  |
  595.     //  |      |       | LOCATION |                                     |
  596.     //  +------+-------+----------+-------------------------------------+
  597.     //  |  00  |   3   |   49152  | ($C000-$FFFF)*                      |
  598.     //  |  01  |   2   |   32768  | ($8000-$BFFF)                       |
  599.     //  |  10  |   1   |   16384  | ($4000-$7FFF)*                      |
  600.     //  |  11  |   0   |       0  | ($0000-$3FFF) (DEFAULT VALUE)       |
  601.     //  +------+-------+----------+-------------------------------------+
  602.     .var bits=%11
  603.  
  604.     .if (bank==0) .eval bits=%11
  605.     .if (bank==1) .eval bits=%10
  606.     .if (bank==2) .eval bits=%01
  607.     .if (bank==3) .eval bits=%00
  608.  
  609.     .print "bits=%" + toBinaryString(bits)
  610.  
  611.     //
  612.     // Set Data Direction for CIA #2, Port A to output
  613.     //
  614.     lda $dd02
  615.     and #%11111100  // Mask the bits we're interested in.
  616.     ora #$03        // Set bits 0 and 1.
  617.     sta $dd02
  618.  
  619.     //
  620.     // Tell VIC-II to switch to bank
  621.     //
  622.     lda $dd00
  623.     and #%11111100
  624.     ora #bits
  625.     sta $dd00
  626. }
  627.  
  628. //
  629. // Enter hires bitmap mode (a.k.a. standard bitmap mode)
  630. //
  631. .macro SetHiresBitmapMode() {
  632.     //
  633.     // Clear extended color mode (bit 6) and set bitmap mode (bit 5)
  634.     //
  635.     lda $d011
  636.     and #%10111111
  637.     ora #%00100000
  638.     sta $d011
  639.  
  640.     //
  641.     // Clear multi color mode (bit 4)
  642.     //
  643.     lda $d016
  644.     and #%11101111
  645.     sta $d016
  646. }
  647.  
  648.  
  649. //
  650. // Switch location of screen memory.
  651. //
  652. // Args:
  653. //   address: Address relative to current VIC-II bank base address.
  654. //            Valid values: $0000-$3c00. Must be a multiple of $0400.
  655. //
  656. .macro SetScreenMemory(address) {
  657.     //
  658.     // The most significant nibble of $D018 selects where the screen is
  659.     // located in the current VIC-II bank.
  660.     //
  661.     //  +------------+-----------------------------+
  662.     //  |            |         LOCATION*           |
  663.     //  |    BITS    +---------+-------------------+
  664.     //  |            | DECIMAL |        HEX        |
  665.     //  +------------+---------+-------------------+
  666.     //  |  0000XXXX  |      0  |  $0000            |
  667.     //  |  0001XXXX  |   1024  |  $0400 (DEFAULT)  |
  668.     //  |  0010XXXX  |   2048  |  $0800            |
  669.     //  |  0011XXXX  |   3072  |  $0C00            |
  670.     //  |  0100XXXX  |   4096  |  $1000            |
  671.     //  |  0101XXXX  |   5120  |  $1400            |
  672.     //  |  0110XXXX  |   6144  |  $1800            |
  673.     //  |  0111XXXX  |   7168  |  $1C00            |
  674.     //  |  1000XXXX  |   8192  |  $2000            |
  675.     //  |  1001XXXX  |   9216  |  $2400            |
  676.     //  |  1010XXXX  |  10240  |  $2800            |
  677.     //  |  1011XXXX  |  11264  |  $2C00            |
  678.     //  |  1100XXXX  |  12288  |  $3000            |
  679.     //  |  1101XXXX  |  13312  |  $3400            |
  680.     //  |  1110XXXX  |  14336  |  $3800            |
  681.     //  |  1111XXXX  |  15360  |  $3C00            |
  682.     //  +------------+---------+-------------------+
  683.     //
  684.     .var bits = (address / $0400) << 4
  685.  
  686.     lda $d018
  687.     and #%00001111
  688.     ora #bits
  689.     sta $d018
  690. }
  691.  
  692.  
  693. //
  694. // Set location of bitmap.
  695. //
  696. // Args:
  697. //    address: Address relative to VIC-II bank address.
  698. //             Valid values: $0000 (bitmap at $0000-$1FFF)
  699. //                           $2000 (bitmap at $2000-$3FFF)
  700. //
  701. .macro SetBitmapAddress(address) {
  702.     //
  703.     // In standard bitmap mode the location of the bitmap area can
  704.     // be set to either BANK address + $0000 or BANK address + $2000
  705.     //
  706.     // By setting bit 3, we can configure which of the locations to use.
  707.     //
  708.  
  709.     .var bits=0
  710.  
  711.     lda $d018
  712.  
  713.     .if (address == $0000) {            // this is chosen > bitmap address =
  714.         and #%11110111
  715.     }
  716.  
  717.     .if (address == $2000) {
  718.         ora #%00001000
  719.     }
  720.  
  721.     .if (address == $0c00) {
  722.         lda #%00111000
  723.     }
  724.  
  725.     sta $d018
  726. }
  727.  
  728. .macro ResetStandardBitMapMode() {
  729.     lda $d011
  730.     and #%11011111
  731.     sta $d011
  732. }
  733.  
  734. // This is the code that goes in at the top before the code that is required is executed
  735. .macro SwitchScreenBufferTop() {
  736. //    lda switch_flag
  737. //    bne use_screen2
  738. //    // clear first buffer (if required)
  739. //    // <CODE GOES IN HERE>
  740. //    jsr ClearBitmapBuffer1
  741. //    jmp skip_use_screen2            // switch from buffer2 to buffer1
  742. //use_screen2:
  743. //    // clear second buffer (if required)
  744. //    // <CODE GOES IN HERE>
  745. //    jsr ClearBitmapBuffer2
  746. //skip_use_screen2:
  747.     // Need to figure out which screen buffer we are going to clear; e.g. the one that is not visible
  748.     lda switch_flag
  749.     bne use_screen2_clear_bitmap                // if switch_flag = 1 then clear secondary screen buffer. We are drawing to primary
  750.     jsr ClearBitmapBuffer2_partial_bottom
  751.     jmp finished_clearing_bitmaps
  752. use_screen2_clear_bitmap:
  753.     jsr ClearBitmapBuffer1_partial_bottom
  754. finished_clearing_bitmaps:
  755. }
  756.  
  757. // This is the code that goes in at the bottom after the code that is required is executed
  758. .macro SwitchScreenBufferBottom() {
  759.     // Time to switch buffers again as we are dooooone!
  760.     lda switch_flag
  761.     bne secondary_screen_buffer_active
  762.     jsr alt_mem
  763.     jmp skip_alt_mem
  764. secondary_screen_buffer_active:
  765.     jsr pref_mem  
  766. skip_alt_mem:
  767.     lda switch_flag
  768.     eor #$01
  769.     sta switch_flag                 // switchs flag for double buffering
  770. }
  771.  
  772. .macro FillBitmap(addr, value) {
  773.     ldx #$00
  774.     lda #value
  775. !loop:
  776.     sta addr,x
  777.     sta (addr + $100),x
  778.     sta (addr + $200),x
  779.     sta (addr + $300),x
  780.     sta (addr + $400),x
  781.     sta (addr + $500),x
  782.     sta (addr + $600),x
  783.     sta (addr + $700),x
  784.     sta (addr + $800),x
  785.     sta (addr + $900),x
  786.     sta (addr + $a00),x
  787.     sta (addr + $b00),x
  788.     sta (addr + $c00),x
  789.     sta (addr + $d00),x
  790.     sta (addr + $e00),x
  791.     sta (addr + $f00),x
  792.     sta (addr + $1000),x
  793.     sta (addr + $1100),x
  794.     sta (addr + $1200),x
  795.     sta (addr + $1300),x
  796.     sta (addr + $1400),x
  797.     sta (addr + $1500),x
  798.     sta (addr + $1600),x
  799.     sta (addr + $1700),x
  800.     sta (addr + $1800),x
  801.     sta (addr + $1900),x
  802.     sta (addr + $1a00),x
  803.     sta (addr + $1b00),x
  804.     sta (addr + $1c00),x
  805.     sta (addr + $1d00),x
  806.     sta (addr + $1e00),x
  807.     sta (addr + $1f00),x
  808.     dex
  809.     bne !loop-
  810. }
  811.  
  812. //
  813. // Fill screen memory with a value.
  814. //
  815. // Args:
  816. //      address: Absolute base address of screen memory.
  817. //      value: byte value to fill screen memory with
  818. //
  819. .macro FillScreenMemory(address, value) {
  820.     //
  821.     // Screen memory is 40 * 25 = 1000 bytes ($3E8 bytes)
  822.     //
  823.     ldx #$00
  824.     lda #value
  825.     // fill the first 255*3=765 bytes
  826. !loop:
  827.     sta address,x
  828.     sta (address + $100),x
  829.     sta (address + $200),x
  830.     dex
  831.     bne !loop-
  832.  
  833.     // fill the last 232 bytes; e.g.
  834.     ldx #$e8
  835. !loop:
  836.     sta (address + $2ff),x     // Start one byte below the area we're clearing
  837.                                // That way we can bail directly when zero without an additional comparison
  838.     dex
  839.     bne !loop-
  840. }
  841.  
  842. .macro CopyBitmap(sourceaddr, destaddr) {
  843.     ldx #$00
  844. copy_bitmap_loop:
  845.     lda sourceaddr,x
  846.     sta destaddr,x
  847.     lda (sourceaddr + $100),x
  848.     sta (destaddr + $100),x
  849.     lda (sourceaddr + $200),x
  850.     sta (destaddr + $200),x
  851.     lda (sourceaddr + $300),x
  852.     sta (destaddr + $300),x
  853.     lda (sourceaddr + $400),x
  854.     sta (destaddr + $400),x
  855.     lda (sourceaddr + $500),x
  856.     sta (destaddr + $500),x
  857.     lda (sourceaddr + $600),x
  858.     sta (destaddr + $600),x
  859.     lda (sourceaddr + $700),x
  860.     sta (destaddr + $700),x
  861.     lda (sourceaddr + $800),x
  862.     sta (destaddr + $800),x
  863.     lda (sourceaddr + $900),x
  864.     sta (destaddr + $900),x
  865.     lda (sourceaddr + $a00),x
  866.     sta (destaddr + $a00),x
  867.     lda (sourceaddr + $b00),x
  868.     sta (destaddr + $b00),x
  869.     lda (sourceaddr + $c00),x
  870.     sta (destaddr + $c00),x
  871.     lda (sourceaddr + $d00),x
  872.     sta (destaddr + $d00),x
  873.     lda (sourceaddr + $e00),x
  874.     sta (destaddr + $e00),x
  875.     lda (sourceaddr + $f00),x
  876.     sta (destaddr + $f00),x
  877.     lda (sourceaddr + $1000),x
  878.     sta (destaddr + $1000),x
  879.     lda (sourceaddr + $1100),x
  880.     sta (destaddr + $1100),x
  881.     lda (sourceaddr + $1200),x
  882.     sta (destaddr + $1200),x
  883.     lda (sourceaddr + $1300),x
  884.     sta (destaddr + $1300),x
  885.     lda (sourceaddr + $1400),x
  886.     sta (destaddr + $1400),x
  887.     lda (sourceaddr + $1500),x
  888.     sta (destaddr + $1500),x
  889.     lda (sourceaddr + $1600),x
  890.     sta (destaddr + $1600),x
  891.     lda (sourceaddr + $1700),x
  892.     sta (destaddr + $1700),x
  893.     lda (sourceaddr + $1800),x
  894.     sta (destaddr + $1800),x
  895.     lda (sourceaddr + $1900),x
  896.     sta (destaddr + $1900),x
  897.     lda (sourceaddr + $1a00),x
  898.     sta (destaddr + $1a00),x
  899.     lda (sourceaddr + $1b00),x
  900.     sta (destaddr + $1b00),x
  901.     lda (sourceaddr + $1c00),x
  902.     sta (destaddr + $1c00),x
  903.     lda (sourceaddr + $1d00),x
  904.     sta (destaddr + $1d00),x
  905.     lda (sourceaddr + $1e00),x
  906.     sta (destaddr + $1e00),x
  907.     lda (sourceaddr + $1f00),x
  908.     sta (destaddr + $1f00),x
  909.     dex
  910.     txa
  911.     cmp #0
  912.     beq done
  913.     jmp copy_bitmap_loop
  914. done:
  915.     //bne copy_bitmap_loop
  916. }
  917.  
  918. //
  919. // Copy screen memory with a value. Used typically to copy color scheme for bitmap
  920. //
  921. // Args:
  922. //      sourceaddress: Absolute base address of screen memory.
  923. //      sourceaddress: Absolute base address of screen memory.
  924. //
  925. .macro CopyScreenMemory(sourceaddr, destaddr) {
  926.     //
  927.     // Screen memory is 40 * 25 = 1000 bytes ($3E8 bytes)
  928.     //
  929.     ldx #$00
  930. copy_loop_1:
  931.     lda sourceaddr,x
  932.     sta destaddr,x
  933.     lda (sourceaddr + $100),x
  934.     sta (destaddr + $100),x
  935.     lda (sourceaddr + $200),x
  936.     sta (destaddr + $200),x
  937.     dex
  938.     bne copy_loop_1
  939.  
  940.     ldx #$e8
  941. copy_loop_2:
  942.     lda (sourceaddr + $2ff),x     // Start one byte below the area we're clearing
  943.     sta (destaddr + $2ff),x       // Start one byte below the area we're clearing
  944.                                   // That way we can bail directly when zero without an additional comparison
  945.     dex
  946.     bne copy_loop_2
  947. }
  948.  
  949. .macro SetupIRQ(IRQaddr,IRQline,IRQlineHi) {
  950.     lda #$7f        // Disable CIA IRQ's
  951.     sta $dc0d
  952.     sta $dd0d
  953.  
  954.     lda #<IRQaddr   // Install RASTER IRQ
  955.     ldx #>IRQaddr   // into Hardware
  956.     sta $fffe       // Interrupt Vector
  957.     stx $ffff
  958.  
  959.     lda #$01        // Enable RASTER IRQs
  960.     sta $d01a
  961.     lda #IRQline    // IRQ raster line
  962.     sta $d012
  963.     .if (IRQline > 255) {
  964.         .error "supports only less than 256 lines"
  965.     }
  966.     lda $d011   // clear IRQ raster line bit 8
  967.     and #$7f
  968.     sta $d011
  969.  
  970.     asl $d019  // Ack any previous raster interrupt
  971.     bit $dc0d  // reading the interrupt control registers
  972.     bit $dd0d  // clears them
  973. }
  974. //----------------------------------------------------------
  975. .macro EndIRQ(nextIRQaddr,nextIRQline,IRQlineHi) {
  976.     asl $d019
  977.     lda #<nextIRQaddr
  978.     sta $fffe
  979.     lda #>nextIRQaddr
  980.     sta $ffff
  981.     lda #nextIRQline
  982.     sta $d012
  983.     .if(IRQlineHi) {
  984.         lda $d011
  985.         ora #$80
  986.         sta $d011
  987.     }
  988. }
  989.  
  990. .macro irq_start(end_lbl) {
  991.     sta end_lbl-6
  992.     stx end_lbl-4
  993.     sty end_lbl-2
  994. }
  995.  
  996. .macro irq_end(next, line) {
  997.     EndRasterIRQ(next, line, false)
  998.     lda #$00
  999.     ldx #$00
  1000.     ldy #$00
  1001.     rti
  1002. }
  1003.  
  1004. // Setup stable raster IRQ NOTE: cannot be set on a badline or the second
  1005. // interrupt happens before we store the stack pointer (among other things)
  1006. .macro double_irq(end, stableIRQ) {
  1007.     //The CPU cycles spent to get in here                           [7]
  1008.     irq_start(end) // 4+4+4 cycles
  1009.  
  1010.     lda #<stableIRQ     // Set IRQ Vector                           [4]
  1011.     ldx #>stableIRQ     // to point to the                          [4]
  1012.                         // next part of the
  1013.     sta $fffe           // Stable IRQ                               [4]
  1014.     stx $ffff           //                                          [4]
  1015.     inc $d012           // set raster interrupt to the next line    [6]
  1016.     asl $d019           // Ack raster interrupt                     [6]
  1017.     tsx                 // Store the stack pointer!                 [2]
  1018.     cli                 //                                          [2]
  1019.     // Total spent cycles up to this point                          [51]
  1020.     nop        //                                                   [53]
  1021.     nop        //                                                   [55]
  1022.     nop        //                                                   [57]
  1023.     nop        //                                                   [59]
  1024.     nop        //Execute nop's                                      [61]
  1025.     nop        //until next RASTER                                  [63]
  1026.     nop        //IRQ Triggers
  1027. }
  1028.  
  1029.  
  1030. //----------------------------------------------------------
  1031. // Sample source call: SetupIRQ(irq_part1_0, irq0line, false)
  1032. //----------------------------------------------------------
  1033. .macro SetupRasterIRQ(IRQaddr,IRQline,IRQlineHi) {
  1034.     lda #$7f        // Disable CIA IRQ's
  1035.     sta $dc0d
  1036.     sta $dd0d
  1037.  
  1038.     lda #<IRQaddr   // Install RASTER IRQ
  1039.     ldx #>IRQaddr   // into Hardware
  1040.     sta $fffe       // Interrupt Vector
  1041.     stx $ffff
  1042.  
  1043.     lda #$01        // Enable RASTER IRQs
  1044.     sta $d01a
  1045.     lda #IRQline    // IRQ raster line
  1046.     sta $d012
  1047.     .if (IRQline > 255) {
  1048.         .error "supports only less than 256 lines"
  1049.     }
  1050.     lda $d011   // clear IRQ raster line bit 8
  1051.     and #$7f
  1052.     sta $d011
  1053.  
  1054.     asl $d019  // Ack any previous raster interrupt
  1055.     bit $dc0d  // reading the interrupt control registers
  1056.     bit $dd0d  // clears them
  1057. }
  1058. //----------------------------------------------------------
  1059. .macro EndRasterIRQ(nextIRQaddr,nextIRQline,IRQlineHi) {
  1060.     asl $d019
  1061.     lda #<nextIRQaddr
  1062.     sta $fffe
  1063.     lda #>nextIRQaddr
  1064.     sta $ffff
  1065.     lda #nextIRQline
  1066.     sta $d012
  1067.     .if(IRQlineHi) {
  1068.         lda $d011
  1069.         ora #$80
  1070.         sta $d011
  1071.     }
  1072. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement