Upgrade to Pro — share decks privately, control downloads, hide ads and more …

"Raster Shadery" na Commodore 64

"Raster Shadery" na Commodore 64

Karty graficzne mogą uruchamiać małe programy gdy pixel jest wyświetlany na ekranie.

Commodore 64 może uruchamiać małe programy gdy linia rastra jest wyświetlana na telewizorze.

Pixel Shadery mogą być używane do tworzenia realistycznego oświetlenia, efektów specjalnych, a nawet do obliczeń fizycznych!

“Raster Shadery” mogą być używane do dzielenia ekranu, wyświetlania dodatkowych sprajtów, a nawet do odtwarzania dźwięku.

Ale dość gadania.

Pokodujmy

85977ebfe59c2ee669f2196930f1a701?s=128

Michał Taszycki

June 03, 2016
Tweet

Transcript

  1. “Raster Shadery” na

  2. Nie pozwalam zginąć starym komputerom mehowte  Michał Taszycki na

  3. Tworzę cotygodniowy kurs wideo o programowaniu C64 64bites.com/raster-shadery

  4. Commodore 64 to przeszłość

  5. Dziś

  6. Kiedyś

  7. Dziś

  8. Kiedyś

  9. Kiedyś

  10. Kiedyś ?

  11. Dziś!

  12. Pixel Shader varying vec3 N; varying vec3 v; void main(void)

    { vec3 L = normalize(gl_LightSource[0].position.xyz - v); vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0); Idiff = clamp(Idiff, 0.0, 1.0); gl_FragColor = Idiff; }
  13. “Raster Shader” irq: lda #$ff sta $d019 ldx #$05 d:

    dex bne d ldx #$00 c: ldy #$08 a: lda colors,x sta $d020 sta $d021 inx dey beq c txa ldx #$07 b: dex bne b tax cpx #$8c bcc a
  14. Dosyć gadania!

  15. Pokodujmy!

  16. Minimalny program :BasicUpstart2(main) main: rts

  17. None
  18. LDA adres LDA #wartość Pamięć RAM ➞ Rejestr A STA

    adres Rejestr A ➞ Pamięć RAM Najważniejsze instrukcje
  19. rts main: lda # sta background_color lda # sta border_color

    GRAY DARK_GRAY Kolory ramki i tła .label border_color = $d020 .label background_color = $d021 :BasicUpstart2(main)
  20. Makra rts main: lda # sta background_color lda # sta

    border_color GRAY DARK_GRAY
  21. Makra rts main: lda # sta background_color lda # sta

    border_color GRAY DARK_GRAY .macro background(color) { }
  22. lda # sta background_color Makra rts main: :background( ) color

    lda # sta border_color GRAY DARK_GRAY .macro background(color) { }
  23. lda # sta background_color Makra rts main: :background( ) color

    lda # sta border_color GRAY DARK_GRAY .macro background(color) { }
  24. lda # sta background_color Makra rts main: .macro border(color) {

    } :background( ) color lda # sta border_color GRAY DARK_GRAY .macro background(color) { }
  25. :border( ) .macro background(color) { } lda # sta background_color

    Makra rts main: .macro border(color) { } :background( ) color lda # sta border_color GRAY DARK_GRAY color
  26. None
  27. Raster Bar // long delay :background(BLACK) :background(DARK_GRAY)

  28. Opóźnienie :background(BLACK) :background(DARK_GRAY) nop

  29. Opóźnienie :background(BLACK) :background(DARK_GRAY) nop nop

  30. Opóźnienie :background(BLACK) :background(DARK_GRAY) nop nop nop

  31. Opóźnienie :background(BLACK) :background(DARK_GRAY) nop // ... many more nops nop

    nop
  32. Opóźnienie :background(BLACK) :background(DARK_GRAY) .for (var i = 0; i <

    ; i++) { nop } 230
  33. Opóźnienie .macro nops( ) { } .for (var i =

    0; i < ; i++) { nop } :background(BLACK) :background(DARK_GRAY) 230 count
  34. Opóźnienie :nops( ) .macro nops( ) { } .for (var

    i = 0; i < ; i++) { nop } :background(BLACK) :background(DARK_GRAY) 230 count count
  35. Przerwania raster_bars_irq: jmp irq_handler :nops( ) :background(BLACK) :background(DARK_GRAY) 230

  36. Przerwania // Disable IRQ handling sei // inject the handler

    lda #<raster_bars_irq sta irq_vector lda #>raster_bars_irq sta irq_vector + 1 // Enable IRQ handling cli
  37. None
  38. // inject the handler lda #<raster_bars_irq sta irq_vector lda #>raster_bars_irq

    sta irq_vector + 1 Wyłączamy timer cli sei
  39. Wyłączamy timer cli sei

  40. Wyłączamy timer cli sei // Disable the interrupt generated by

    timers lda #%01111111 sta cia1_interrupt_control_register sta cia2_interrupt_control_register // Negate already scheduled interrupts lda cia1_interrupt_control_register lda cia2_interrupt_control_register
  41. Włączamy raster cli sei // Disable the interrupt generated by

    timers lda #%01111111 sta cia1_interrupt_control_register sta cia2_interrupt_control_register // Negate already scheduled interrupts lda cia1_interrupt_control_register lda cia2_interrupt_control_register // Enable raster interrupts lda #%00000001 sta vic2_interrupt_control_register
  42. Wybieramy linię rastra cli sei // Disable the interrupt generated

    by timers lda #%01111111 sta cia1_interrupt_control_register sta cia2_interrupt_control_register // Negate already scheduled interrupts lda cia1_interrupt_control_register lda cia2_interrupt_control_register // Enable raster interrupts lda #%00000001 sta vic2_interrupt_control_register :request_raster_irq(106, raster_bars_irq)
  43. Wybieramy linię rastra .macro request_raster_irq(line_number, handler) { }

  44. .macro request_raster_irq(line_number, handler) { } Wybieramy linię rastra lda #<handler

    sta irq_vector lda #>handler sta irq_vector + 1
  45. .macro request_raster_irq(line_number, handler) { } Wybieramy linię rastra lda #<handler

    sta irq_vector lda #>handler sta irq_vector + 1 lda #line_number sta vic2_rasterline_register
  46. .macro request_raster_irq(line_number, handler) { } Wybieramy linię rastra lda #<handler

    sta irq_vector lda #>handler sta irq_vector + 1 .if (line_number > 255) { :set_bits(screen_control_register, %10000000) } else { :clear_bits(screen_control_register, %10000000) } lda #line_number sta vic2_rasterline_register
  47. Wybieramy linię rastra .macro set_bits(address, bit_mask) { lda address ora

    #bit_mask sta address } .macro clear_bits(address, bit_mask) { lda address and #255 - bit_mask sta address }
  48. Przerwanie obsłużone? jmp irq_handler raster_bars_irq: :background(BLACK) :nops(230) :background(DARK_GRAY)

  49. Przerwanie obsłużone? raster_bars_irq: :background(BLACK) :nops(230) :background(DARK_GRAY) lda #%00000001 sta vic2_interrupt_status_register

    jmp irq_handler
  50. Przerwanie obsłużone? raster_bars_irq: :background(BLACK) :nops(230) :background(DARK_GRAY) :exit_irq_handler() .macro exit_irq_handler() {

    } lda #%00000001 sta vic2_interrupt_status_register jmp irq_handler
  51. None
  52. Stabilizacja :exit_irq_handler() raster_bars_irq: :nops(14) :background(BLACK) :nops(230) :background(DARK_GRAY)

  53. None
  54. Raster Bars! :exit_irq_handler() raster_bars_irq:

  55. :nops(14) :background(BLACK) :nops(4) :background(DARK_GRAY) :nops(29) :background(GRAY) :nops(29) :background(LIGHT_GRAY) :nops(29) :background(WHITE)

    Raster Bars! :exit_irq_handler() raster_bars_irq:
  56. :nops(14) :background(BLACK) :nops(4) :background(DARK_GRAY) :nops(29) :background(GRAY) :nops(29) :background(LIGHT_GRAY) :nops(29) :background(WHITE)

    Raster Bars! :exit_irq_handler() raster_bars_irq: // ...
  57. :nops(14) :background(BLACK) :nops(4) :background(DARK_GRAY) :nops(29) :background(GRAY) :nops(29) :background(LIGHT_GRAY) :nops(29) :background(WHITE)

    Raster Bars! :exit_irq_handler() raster_bars_irq: // ... // ...
  58. :nops(14) :background(BLACK) :nops(4) :background(DARK_GRAY) :nops(29) :background(GRAY) :nops(29) :background(LIGHT_GRAY) :nops(29) :background(WHITE)

    Raster Bars! :exit_irq_handler() raster_bars_irq: :nops(29) :background(LIGHT_GRAY) :nops(29) :background(GRAY) :nops(29) :background(DARK_GRAY) :nops(29) :background(BLACK) :nops(4) :background(DARK_GRAY) // ... // ...
  59. None
  60. Sprzętowe duszki

  61. // Enable all 8 sprites lda #%11111111 sta sprites.enable_bits Sprzętowe

    duszki
  62. // Enable all 8 sprites lda #%11111111 sta sprites.enable_bits .for

    (var i = 0; i < 8; i++) { :set_sprite_position_x(i, 60 + 32 * i) } Sprzętowe duszki
  63. .macro set_sprite_position_x(index, position_x) { } Sprzętowe duszki

  64. .macro set_sprite_position_x(index, position_x) { } lda #position_x sta sprites.positions +

    index*2 + 0 Sprzętowe duszki
  65. .macro set_sprite_position_x(index, position_x) { } .if (position_x > 255) {

    :set_bits(sprites.position_x_high_bits,1<<index) } else { :clear_bits(sprites.position_x_high_bits,1<<index) } lda #position_x sta sprites.positions + index*2 + 0 Sprzętowe duszki
  66. Więcej przerwań raster_bars_irq: :exit_irq_handler() // ... :nops(14)

  67. sprite_row_irq1: :exit_irq_handler() // ... raster_bars_irq: :exit_irq_handler() // ... :nops(14) Więcej

    przerwań
  68. sprite_row_irq1: :exit_irq_handler() // ... raster_bars_irq: :exit_irq_handler() // ... :request_raster_irq(60, sprite_row_irq1)

    :nops(14) Więcej przerwań
  69. sprite_row_irq1: :exit_irq_handler() // ... :request_raster_irq(106, raster_bars_irq) raster_bars_irq: :exit_irq_handler() // ...

    :request_raster_irq(60, sprite_row_irq1) :nops(14) Więcej przerwań
  70. sprite_row_irq1: :exit_irq_handler() // Set the y-position, bitmaps and colors :sprites_row(70,

    0, 3) raster_bars_irq: :exit_irq_handler() // ... :request_raster_irq(60, sprite_row_irq1) :request_raster_irq(106, raster_bars_irq) :nops(14) Więcej przerwań
  71. None
  72. sprite_row_irq1: :exit_irq_handler() // Set the y-position, bitmaps and colors :sprites_row(70,

    0, 3) Raster time raster_bars_irq: :exit_irq_handler() // ... :request_raster_irq(60, sprite_row_irq1) :request_raster_irq(106, raster_bars_irq) :nops(14)
  73. sprite_row_irq1: :exit_irq_handler() // Set the y-position, bitmaps and colors :sprites_row(70,

    0, 3) Raster time raster_bars_irq: :exit_irq_handler() // ... :request_raster_irq(60, sprite_row_irq1) :request_raster_irq(106, raster_bars_irq) :border(RED) :border(GRAY) :nops(14)
  74. sprite_row_irq1: :exit_irq_handler() // Set the y-position, bitmaps and colors :sprites_row(70,

    0, 3) Raster time raster_bars_irq: :exit_irq_handler() // ... :request_raster_irq(60, sprite_row_irq1) :request_raster_irq(106, raster_bars_irq) :nops(14) :border(RED) :border(GRAY) :border(GRAY) :border(ORANGE)
  75. sprite_row_irq1: :exit_irq_handler() // Set the y-position, bitmaps and colors :sprites_row(70,

    0, 3) Raster time raster_bars_irq: :exit_irq_handler() // ... :request_raster_irq(60, sprite_row_irq1) :request_raster_irq(106, raster_bars_irq) :nops(7) :border(RED) :border(GRAY) :border(GRAY) :border(ORANGE)
  76. None
  77. Więcej duszków raster_bars_irq: :request_raster_irq( ) :exit_irq_handler() 60, sprite_row_irq1 sprite_row_irq1: //

    ... // ...
  78. raster_bars_irq: :request_raster_irq( ) :exit_irq_handler() sprite_row_irq2: :border(CYAN) :sprites_row(160, 8, 12) :border(GRAY)

    :request_raster_irq( ) :exit_irq_handler() 60, sprite_row_irq1 sprite_row_irq1: // ... // ... Więcej duszków
  79. raster_bars_irq: :request_raster_irq( ) :exit_irq_handler() sprite_row_irq2: :border(CYAN) :sprites_row(160, 8, 12) :border(GRAY)

    :request_raster_irq( ) :exit_irq_handler() 60, sprite_row_irq1 sprite_row_irq1: // ... // ... 150, sprite_row_irq2 Więcej duszków
  80. None
  81. Cienka zielona linia… :request_raster_irq(248, open_border_irq) open_border_irq: :border(GREEN) :nops(14) :border(GRAY) :request_raster_irq(60,

    sprite_row_irq1) :exit_irq_handler()
  82. None
  83. None
  84. Otwieranie ramki sprite_row_irq2: :request_raster_irq(248, open_border_irq) :exit_irq_handler() open_border_irq: :request_raster_irq(60, sprite_row_irq1) :exit_irq_handler()

  85. sprite_row_irq2: :request_raster_irq(248, open_border_irq) :exit_irq_handler() open_border_irq: :request_raster_irq(60, sprite_row_irq1) :exit_irq_handler() // Enable

    25 lines mode :set_bits(screen_control_register, %00001000) Otwieranie ramki
  86. sprite_row_irq2: :request_raster_irq(248, open_border_irq) :exit_irq_handler() open_border_irq: :request_raster_irq(60, sprite_row_irq1) :exit_irq_handler() // Enable

    24 lines mode :clear_bits(screen_control_register, %00001000) // Enable 25 lines mode :set_bits(screen_control_register, %00001000) Otwieranie ramki
  87. None
  88. Rysowanie pod ramką lda #%10110101 sta border_pattern

  89. None
  90. None
  91. Muzyka

  92. Muzyka // Import music from a file .pc=$1000 music: .import

    binary "music.bin"
  93. Muzyka main: // initialize music jsr music // Import music

    from a file .pc=$1000 music: .import binary "music.bin"
  94. Muzyka main: // initialize music jsr music // Import music

    from a file .pc=$1000 music: .import binary "music.bin" play_music: :border(YELLOW) jsr $music + 3 :border(GRAY) :request_raster_irq(248, open_border_irq) :exit_irq_handler()
  95. None
  96. Spróbuj na własną ręke!

  97. Spróbuj na własną ręke! 64bites.com/raster-shadery

  98. Spróbuj na własną ręke! kod źródłowy 64bites.com/raster-shadery

  99. Spróbuj na własną ręke! kod źródłowy slajdy 64bites.com/raster-shadery

  100. Spróbuj na własną ręke! 64bites.com/raster-shadery kod źródłowy slajdy