1.1 --- a/vga.S Wed May 10 00:07:28 2017 +0200
1.2 +++ b/vga.S Wed May 10 00:08:19 2017 +0200
1.3 @@ -21,6 +21,9 @@
1.4 #include "pic32.h"
1.5
1.6 #define HFREQ_LIMIT 627 /* 20MHz cycles */
1.7 +#define HSYNC_LIMIT 16 /* bytes or pixels */
1.8 +#define LINE_LIMIT 160 /* bytes or pixels */
1.9 +
1.10 #define VSYNC_START 1 /* horizontal lines, front porch end */
1.11 #define VISIBLE_START 4 /* horizontal lines */
1.12 #define VBP_START 516 /* horizontal lines, back porch start */
1.13 @@ -72,13 +75,13 @@
1.14
1.15 /* Get the RAM size. */
1.16
1.17 - la $v0, BMXDRMSZ
1.18 + la $v0, BMXDRMSZ
1.19 lw $v0, 0($v0)
1.20
1.21 /* Initialise the stack pointer. */
1.22
1.23 - lui $v1, 0x8000 /* 0x80000000 */
1.24 - addu $sp, $v0, $v1 /* sp = 0x80000000 + RAM size */
1.25 + li $v1, KSEG0_BASE
1.26 + addu $sp, $v0, $v1 /* sp = KSEG0_BASE + RAM size */
1.27
1.28 /* Initialise the globals pointer. */
1.29
1.30 @@ -100,6 +103,21 @@
1.31 jal init_timer1
1.32 nop
1.33
1.34 + /* Initialise PMP. */
1.35 +
1.36 + jal init_pmp
1.37 + nop
1.38 +
1.39 + /* Initialise DMA. */
1.40 +
1.41 + jal init_dma
1.42 + nop
1.43 +
1.44 + /* Initialise framebuffer. */
1.45 +
1.46 + jal init_framebuffer
1.47 + nop
1.48 +
1.49 /* Enable interrupts and loop. */
1.50
1.51 jal enable_interrupts
1.52 @@ -108,20 +126,27 @@
1.53 jal handle_error_level
1.54 nop
1.55
1.56 + /* Main program. */
1.57 +
1.58 li $a1, 20000000 /* counter = 20000000 */
1.59 - li $a2, 6374 /* test timer scaling */
1.60 + li $a2, 3187 /* test timer scaling */
1.61 +
1.62 + /* Initialise the display state. */
1.63 +
1.64 li $s0, 0 /* line counter */
1.65 la $s1, vfp_active /* current event */
1.66 +
1.67 + /* Monitoring loop. */
1.68 loop:
1.69 - addiu $a1, $a1, -1 /* counter -= 1 */
1.70 - bnez $a1, loop /* until counter == 0 */
1.71 + addiu $a1, $a1, -1 /* counter -= 1 */
1.72 + bnez $a1, loop /* until counter == 0 */
1.73 nop
1.74
1.75 li $a1, 20000000 /* counter = 20000000 */
1.76
1.77 - la $v0, PORTA
1.78 - la $v1, (1 << 2) /* PORTA<2> = RA2 */
1.79 - sw $v1, INV($v0)
1.80 + la $t0, PORTB
1.81 + la $t1, (1 << 10) /* PORTB<10> = RB10 */
1.82 + sw $t1, INV($t0)
1.83
1.84 _next:
1.85 j loop
1.86 @@ -132,37 +157,87 @@
1.87 init_pins:
1.88 /* DEVCFG0<2> needs setting to 0 before the program is run. */
1.89
1.90 - la $v0, CFGCON
1.91 + la $v0, CFGCON
1.92 li $v1, (1 << 3) /* CFGCON<3> = JTAGEN = 0 */
1.93 sw $v1, CLR($v0)
1.94
1.95 +init_outputs:
1.96 + /* Remove analogue features from pins. */
1.97 +
1.98 + la $v0, ANSELA
1.99 + sw $zero, 0($v0) /* ANSELA = 0 */
1.100 + la $v0, ANSELB
1.101 + sw $zero, 0($v0) /* ANSELB = 0 */
1.102 +
1.103 + la $v0, TRISA
1.104 + sw $zero, 0($v0)
1.105 la $v0, TRISB
1.106 - li $v1, (7 << 7) | 15 /* TRISB<9:7> = RB9, RB8, RB7 = 0 */
1.107 - /* sw $v1, CLR($v0) */
1.108 + sw $zero, 0($v0)
1.109 +
1.110 + jr $ra
1.111 + nop
1.112 +
1.113 +
1.114 +
1.115 +/* Interrupt servicing. */
1.116 +
1.117 +.org 0x200
1.118 +
1.119 +interrupt_handler:
1.120 +
1.121 + /* Check for a timer interrupt condition. */
1.122
1.123 - la $v0, PORTB
1.124 - li $v1, (7 << 7) | 15 /* PORTB<9:7> = RB9, RB8, RB7 = 0 */
1.125 - /* sw $v1, CLR($v0) */
1.126 + la $v0, IFS0
1.127 + lw $v1, 0($v0)
1.128 + andi $v1, $v1, (1 << 4) /* T1IF */
1.129 + beqz $v1, irq_next
1.130 + nop
1.131 +
1.132 + /* Timer scaling for testing purposes. */
1.133 +
1.134 + addiu $a2, $a2, -1
1.135 + bnez $a2, irq_clear_timer
1.136 + nop
1.137 + li $a2, 3187
1.138
1.139 -init_leds:
1.140 - la $v0, TRISA
1.141 - li $v1, (1 << 2) /* TRISA<2> = RA2 = 0 */
1.142 + /* Increment the line counter. */
1.143 +
1.144 + addiu $s0, $s0, 1
1.145 +
1.146 + /* Jump to the event handler. */
1.147 +
1.148 + jalr $s1
1.149 + nop
1.150 +
1.151 +irq_clear_timer:
1.152 +
1.153 + /* Clear the timer interrupt condition. */
1.154 +
1.155 + la $v0, IFS0
1.156 + li $v1, (1 << 4) /* IFS0<4> = T1IF = 0 */
1.157 sw $v1, CLR($v0)
1.158
1.159 - la $v0, TRISB
1.160 - li $v1, (3 << 10) /* TRISB<11:10> = RB11, RB10 = 0 */
1.161 +irq_next:
1.162 +
1.163 + /* Check for a PMP interrupt condition. */
1.164 +
1.165 + la $v0, IFS1
1.166 + lw $v1, 0($v0)
1.167 + li $t8, (1 << 16) /* PMPIF */
1.168 + and $v1, $v1, $t8
1.169 + beqz $v1, irq_exit
1.170 + nop
1.171 +
1.172 +irq_clear_pmp:
1.173 +
1.174 + /* Clear the PMP interrupt condition. */
1.175 +
1.176 + la $v0, IFS1
1.177 + li $v1, (1 << 16) /* IFS1<16> = PMPIF = 0 */
1.178 sw $v1, CLR($v0)
1.179
1.180 -clear_leds:
1.181 - la $v0, PORTA
1.182 - li $v1, (1 << 2) /* PORTA<2> = RA2 = 0 */
1.183 - sw $v1, CLR($v0)
1.184 -
1.185 - la $v0, PORTB
1.186 - li $v1, (3 << 10) /* PORTB<11:10> = RB11, RB10 = 0 */
1.187 - sw $v1, CLR($v0)
1.188 -
1.189 - jr $ra
1.190 +irq_exit:
1.191 + eret
1.192 nop
1.193
1.194
1.195 @@ -202,46 +277,120 @@
1.196
1.197
1.198
1.199 -/* Interrupt servicing. */
1.200 +/* Event routines. */
1.201 +
1.202 +/* Start of, and within, the vertical front porch. */
1.203 +
1.204 +vfp_start:
1.205 + /* Clear vsync. */
1.206 +
1.207 + la $v0, PORTB
1.208 + la $v1, (1 << 11) /* PORTB<11> = RB11 */
1.209 + sw $v1, CLR($v0)
1.210
1.211 -.org 0x200
1.212 + /* Enter the active region. */
1.213 +
1.214 + la $s1, vfp_active
1.215
1.216 -interrupt_handler:
1.217 +vfp_active:
1.218 + /* Test for vsync. */
1.219 +
1.220 + subu $v0, $s0, VSYNC_START
1.221 + bnez $v0, _vfp_active_ret
1.222 + nop
1.223 +
1.224 + /* Start the vsync region. */
1.225
1.226 - /* Check for a timer interrupt condition. */
1.227 + la $s1, vsync_start
1.228 +
1.229 +_vfp_active_ret:
1.230 + jr $ra
1.231 + nop
1.232 +
1.233 +
1.234 +
1.235 +/* Start of, and within, vsync. */
1.236 +
1.237 +vsync_start:
1.238 + /* Set vsync. */
1.239
1.240 - la $v0, IFS0
1.241 - lw $v1, 0($v0)
1.242 - and $v1, $v1, (1 << 4) /* T1IF */
1.243 - beqz $v1, irq_exit
1.244 + la $v0, PORTB
1.245 + la $v1, (1 << 11) /* PORTB<11> = RB11 */
1.246 + sw $v1, SET($v0)
1.247 +
1.248 + /* Enter the active region. */
1.249 +
1.250 + la $s1, vsync_active
1.251 +
1.252 +vsync_active:
1.253 + /* Test for visible region. */
1.254 +
1.255 + subu $v0, $s0, VISIBLE_START
1.256 + bnez $v0, _vsync_active_ret
1.257 nop
1.258
1.259 - /* Test timer scaling. */
1.260 -
1.261 - addiu $a2, $a2, -1
1.262 - bnez $a2, irq_clear
1.263 - nop
1.264 - li $a2, 6374
1.265 + /* Start the visible region. */
1.266
1.267 - /* Increment the line counter. */
1.268 -
1.269 - addiu $s0, $s0, 1
1.270 + la $s1, visible_start
1.271
1.272 - /* Jump to the event handler. */
1.273 -
1.274 - jalr $s1
1.275 +_vsync_active_ret:
1.276 + jr $ra
1.277 nop
1.278
1.279 -irq_clear:
1.280 +
1.281 +
1.282 +/* Start of, and within, the visible period. */
1.283
1.284 - /* Clear the timer interrupt condition. */
1.285 +visible_start:
1.286 + /* Clear vsync. */
1.287
1.288 - la $v0, IFS0
1.289 - li $v1, (1 << 4) /* IFS0<4> = T1IF = 0 */
1.290 + la $v0, PORTB
1.291 + la $v1, (1 << 11) /* PORTB<11> = RB11 */
1.292 sw $v1, CLR($v0)
1.293
1.294 -irq_exit:
1.295 - eret
1.296 + /* Enter the active region. */
1.297 +
1.298 + la $s1, visible_active
1.299 +
1.300 +visible_active:
1.301 + /* Initiate hsync transfer and subsequent line transfer. */
1.302 +
1.303 + la $v0, DCH0ECON
1.304 + li $v1, (1 << 7)
1.305 + sw $v1, SET($v0)
1.306 +
1.307 + /* Test for back porch. */
1.308 +
1.309 + subu $v0, $s0, VBP_START
1.310 + bnez $v0, _visible_active_ret
1.311 + nop
1.312 +
1.313 + /* Start the back porch. */
1.314 +
1.315 + la $s1, vbp_active
1.316 +
1.317 +_visible_active_ret:
1.318 + jr $ra
1.319 + nop
1.320 +
1.321 +
1.322 +
1.323 +/* Within the vertical back porch. */
1.324 +
1.325 +vbp_active:
1.326 + /* Test for front porch. */
1.327 +
1.328 + subu $v0, $s0, VBP_END
1.329 + bnez $v0, _vbp_active_ret
1.330 + nop
1.331 +
1.332 + /* Start the front porch. */
1.333 +
1.334 + li $s0, 0
1.335 + la $s1, vfp_start
1.336 +
1.337 +_vbp_active_ret:
1.338 + jr $ra
1.339 nop
1.340
1.341
1.342 @@ -288,118 +437,301 @@
1.343
1.344
1.345
1.346 -/* Event routines. */
1.347 -
1.348 -/* Start of, and within, the vertical front porch. */
1.349 +/* Parallel Master Port initialisation. */
1.350
1.351 -vfp_start:
1.352 - /* Clear vsync. */
1.353 +init_pmp:
1.354 + /* Disable PMP interrupts. */
1.355
1.356 - la $v0, PORTB
1.357 - la $v1, (1 << 10) /* PORTB<10> = RB10 */
1.358 + la $v0, IEC1
1.359 + li $v1, (1 << 16) /* IEC1<16> = PMPIE = 0 */
1.360 sw $v1, CLR($v0)
1.361
1.362 - /* Enter the active region. */
1.363 + /* Initialise PMP.
1.364 +
1.365 + PMCON<12:11> = ADDRMUX<1:0> = 0; demultiplexed address and data
1.366 + PMCON<9> = PTWREN<0> = 0; no write pin
1.367 + PMCON<8> = PTRDEN<0> = 0; no read pin
1.368 + PMCON<7:6> = CSF<1:0> = 0; no chip select pins
1.369 + */
1.370
1.371 - la $s1, vfp_active
1.372 + la $v0, PMCON
1.373 + sw $zero, 0($v0)
1.374
1.375 -vfp_active:
1.376 - /* Test for vsync. */
1.377 + /*
1.378 + PMMODE<14:13> = IRQM<1:0> = 1; interrupt after every read/write
1.379 + PMMODE<12:11> = INCM<1:0> = 0; no increment on every read/write
1.380 + PMMODE<10> = MODE16<0> = 0; 8-bit transfers
1.381 + PMMODE<9:8> = MODE<1:0> = 10; master mode 2
1.382 + PMMODE<5:2> = WAITM<3:0> = 00; single cycle read/write, no chip select wait cycles
1.383 + */
1.384
1.385 - subu $v0, $s0, VSYNC_START
1.386 - bnez $v0, _vfp_active_ret
1.387 - nop
1.388 + la $v0, PMMODE
1.389 + li $v1, 0x2200
1.390 + sw $v1, 0($v0)
1.391 +
1.392 + /* Free non-essential pins for general I/O. */
1.393 +
1.394 + la $v0, PMAEN
1.395 + sw $zero, 0($v0)
1.396
1.397 - /* Start the vsync region. */
1.398 + la $v0, PMADDR
1.399 + sw $zero, 0($v0)
1.400 +
1.401 + la $v0, IFS1
1.402 + li $v1, (3 << 16) /* IFS1<17:16> = PMPEIF, PMPIF = 0 */
1.403 + sw $v1, CLR($v0)
1.404
1.405 - la $s1, vsync_start
1.406 + /* Start PMP mode. */
1.407
1.408 -_vfp_active_ret:
1.409 + la $v0, PMCON
1.410 + li $v1, (1 << 15) /* PMCON<15> = ON = 1 */
1.411 + sw $v1, SET($v0)
1.412 +
1.413 jr $ra
1.414 nop
1.415
1.416
1.417
1.418 -/* Start of, and within, vsync. */
1.419 +/* Direct Memory Access initialisation. */
1.420 +
1.421 +/*
1.422 +Write 16 pixels to the PMP for a hsync pulse. This channel is invoked
1.423 +explicitly in the interrupt handler for Timer1 since it will not happen on every
1.424 +occurrence of the interrupt, but only on those occurrences within the active
1.425 +region of the display output.
1.426 +
1.427 +Write 160 pixels to the PMP for the line data. This is initiated by the
1.428 +completion of the hsync transfer.
1.429 +*/
1.430 +
1.431 +init_dma:
1.432 + /* Disable DMA interrupts. */
1.433
1.434 -vsync_start:
1.435 - /* Set vsync. */
1.436 + la $v0, IEC1
1.437 + li $v1, (7 << 28) /* IEC1<30:28> = DMA2IE, DMA1IE, DMA0IE = 0 */
1.438 + sw $v1, CLR($v0)
1.439 +
1.440 + /* Clear DMA interrupt flags. */
1.441
1.442 - la $v0, PORTB
1.443 - la $v1, (1 << 10) /* PORTB<10> = RB10 */
1.444 + la $v0, IFS1
1.445 + li $v1, (7 << 28) /* IFS1<30:28> = DMA2IF, DMA1IF, DMA0IF = 0 */
1.446 + sw $v1, CLR($v0)
1.447 +
1.448 + /* Enable DMA. */
1.449 +
1.450 + la $v0, DMACON
1.451 + li $v1, (1 << 15)
1.452 sw $v1, SET($v0)
1.453
1.454 - /* Enter the active region. */
1.455 + /*
1.456 + Initialise a hsync channel and a line channel.
1.457 + The hsync channel will be channel 0 (x = 0).
1.458 + The line channel will be channel 1 (x = 1).
1.459 +
1.460 + Once the hsync channel has completed a transfer, the line channel
1.461 + transfer is initiated.
1.462 +
1.463 + Specify a priority of 3:
1.464 + DCHxCON<1:0> = CHPRI<1:0> = 3
1.465 +
1.466 + Auto-enable the channels:
1.467 + DCHxCON<4> = CHAEN = 1
1.468 + */
1.469 +
1.470 + la $v0, DCH0CON
1.471 + li $v1, 0b10011
1.472 + sw $v1, 0($v0)
1.473 +
1.474 + la $v0, DCH1CON
1.475 + li $v1, 0b10011
1.476 + sw $v1, 0($v0)
1.477 +
1.478 + la $v0, DCH2CON
1.479 + li $v1, 0b10011
1.480 + sw $v1, 0($v0)
1.481 +
1.482 + /* Initiate channel transfers when the preceding channel interrupt occurs. */
1.483 +
1.484 + la $v0, DCH0ECON
1.485 + sw $zero, 0($v0)
1.486 +
1.487 + la $v0, DCH1ECON
1.488 + li $v1, (60 << 8) | (1 << 4)
1.489 + sw $v1, 0($v0)
1.490 +
1.491 + la $v0, DCH2ECON
1.492 + li $v1, (61 << 8) | (1 << 4)
1.493 + sw $v1, 0($v0)
1.494
1.495 - la $s1, vsync_active
1.496 + /*
1.497 + The hsync channels have a cell size of 16 bytes:
1.498 + DCHxCSIZ<15:0> = CHCSIZ<15:0> = HSYNC_LIMIT
1.499 +
1.500 + The line channel has a cell size of 160 bytes:
1.501 + DCHxCSIZ<15:0> = CHCSIZ<15:0> = LINE_LIMIT
1.502 + */
1.503 +
1.504 + la $v0, DCH0CSIZ
1.505 + li $v1, HSYNC_LIMIT
1.506 + sw $v1, 0($v0)
1.507 +
1.508 + la $v0, DCH1CSIZ
1.509 + li $v1, HSYNC_LIMIT
1.510 + sw $v1, 0($v0)
1.511 +
1.512 + la $v0, DCH2CSIZ
1.513 + li $v1, LINE_LIMIT
1.514 + sw $v1, 0($v0)
1.515
1.516 -vsync_active:
1.517 - /* Test for visible region. */
1.518 + /*
1.519 + Each source has a size identical to the cell size:
1.520 + DCHxSSIZ<15:0> = CHSSIZ<15:0> = n
1.521 + */
1.522 +
1.523 + la $v0, DCH0SSIZ
1.524 + li $v1, HSYNC_LIMIT
1.525 + sw $v1, 0($v0)
1.526 +
1.527 + la $v0, DCH1SSIZ
1.528 + li $v1, HSYNC_LIMIT
1.529 + sw $v1, 0($v0)
1.530 +
1.531 + la $v0, DCH2SSIZ
1.532 + li $v1, LINE_LIMIT
1.533 + sw $v1, 0($v0)
1.534 +
1.535 + /*
1.536 + The source address is the physical address of either the hsync pulse
1.537 + data or the line data:
1.538 + DCHxSSA = pulse data physical address
1.539 + DCHxSSA = line data physical address
1.540 + */
1.541
1.542 - subu $v0, $s0, VISIBLE_START
1.543 - bnez $v0, _vsync_active_ret
1.544 - nop
1.545 + la $v0, DCH0SSA
1.546 + la $v1, set_ra2
1.547 + li $t8, KSEG0_BASE
1.548 + subu $v1, $v1, $t8
1.549 + sw $v1, 0($v0)
1.550 +
1.551 + la $v0, DCH1SSA
1.552 + sw $v1, 0($v0)
1.553 +
1.554 + la $v0, DCH2SSA
1.555 + sw $zero, 0($v0)
1.556 +
1.557 + /*
1.558 + Each destination has a size of 1 byte:
1.559 + DCHxDSIZ<15:0> = CHDSIZ<15:0> = 1
1.560 + */
1.561 +
1.562 + la $v0, DCH0DSIZ
1.563 + li $v1, 1
1.564 + sw $v1, 0($v0)
1.565 +
1.566 + la $v0, DCH1DSIZ
1.567 + sw $v1, 0($v0)
1.568 +
1.569 + la $v0, DCH2DSIZ
1.570 + sw $v1, 0($v0)
1.571 +
1.572 + /*
1.573 + For the hsync channels, the destination address is the physical address
1.574 + for an I/O register that sets the output signal for hsync:
1.575 + DCHxDSA = physical(PORTA)
1.576 + */
1.577 +
1.578 + la $v0, DCH0DSA
1.579 + li $v1, PORTA + INV
1.580 + li $t8, KSEG1_BASE
1.581 + subu $v1, $v1, $t8
1.582 + sw $v1, 0($v0)
1.583
1.584 - /* Start the visible region. */
1.585 + la $v0, DCH1DSA
1.586 + li $v1, PORTA + CLR
1.587 + li $t8, KSEG1_BASE
1.588 + subu $v1, $v1, $t8
1.589 + sw $v1, 0($v0)
1.590 +
1.591 + /*
1.592 + For the line channel, the destination address is the physical address of
1.593 + PMDIN: DCHxDSA = physical(PMDIN)
1.594 + */
1.595 +
1.596 + la $v0, DCH2DSA
1.597 + li $v1, PMDIN
1.598 + li $t8, KSEG1_BASE
1.599 + subu $v1, $v1, $t8
1.600 + sw $v1, 0($v0)
1.601 +
1.602 + /*
1.603 + The block transfer complete interrupt needs to be enabled, so that upon
1.604 + completion of the transfer, the next transfer can be initiated:
1.605 + DCHxINT<19> = CHBCIE = 1
1.606 + */
1.607
1.608 - la $s1, visible_start
1.609 + la $v0, DCH0INT
1.610 + li $v1, (1 << 19)
1.611 + sw $v1, 0($v0)
1.612 +
1.613 + la $v0, DCH1INT
1.614 + li $v1, (1 << 19)
1.615 + sw $v1, 0($v0)
1.616 +
1.617 + la $v0, DCH2INT
1.618 + sw $zero, 0($v0)
1.619
1.620 -_vsync_active_ret:
1.621 + /* Enable channels. */
1.622 +
1.623 + la $v0, DCH0CON
1.624 + li $v1, 0b10000000
1.625 + sw $v1, SET($v0)
1.626 +
1.627 + la $v0, DCH1CON
1.628 + sw $v1, SET($v0)
1.629 +
1.630 + la $v0, DCH2CON
1.631 + sw $v1, SET($v0)
1.632 +
1.633 jr $ra
1.634 nop
1.635
1.636
1.637
1.638 -/* Start of, and within, the visible period. */
1.639 -
1.640 -visible_start:
1.641 - /* Clear vsync. */
1.642 -
1.643 - la $v0, PORTB
1.644 - la $v1, (1 << 10) /* PORTB<10> = RB10 */
1.645 - sw $v1, CLR($v0)
1.646 -
1.647 - /* Enter the active region. */
1.648 +/* Framebuffer initialisation. */
1.649
1.650 - la $s1, visible_active
1.651 -
1.652 -visible_active:
1.653 - /* NOTE: Perform line activities. */
1.654 +init_framebuffer:
1.655 + li $v0, KSEG0_BASE
1.656 + li $t8, 40 * 1024
1.657 + li $v1, 0xff
1.658
1.659 - la $v0, PORTB
1.660 - la $v1, (1 << 11) /* PORTB<11> = RB11 */
1.661 - sw $v1, INV($v0)
1.662 -
1.663 - /* Test for back porch. */
1.664 -
1.665 - subu $v0, $s0, VBP_START
1.666 - bnez $v0, _visible_active_ret
1.667 +_init_fb_loop:
1.668 + sw $v1, 0($v0)
1.669 + addiu $v0, $v0, 4
1.670 + addiu $t8, $t8, -4
1.671 + bnez $t8, _init_fb_loop
1.672 nop
1.673
1.674 - /* Start the back porch. */
1.675 -
1.676 - la $s1, vbp_active
1.677 -
1.678 -_visible_active_ret:
1.679 jr $ra
1.680 nop
1.681
1.682
1.683
1.684 -/* Within the vertical back porch. */
1.685 -
1.686 -vbp_active:
1.687 - /* Test for front porch. */
1.688 -
1.689 - subu $v0, $s0, VBP_END
1.690 - bnez $v0, _vbp_active_ret
1.691 - nop
1.692 +/* 16 bytes of pulse data used to set PORTA<2> = RA2. */
1.693
1.694 - /* Start the front porch. */
1.695 -
1.696 - li $s0, 0
1.697 - la $s1, vfp_start
1.698 -
1.699 -_vbp_active_ret:
1.700 - jr $ra
1.701 - nop
1.702 +set_ra2:
1.703 +.byte (1 << 2)
1.704 +.byte (1 << 2)
1.705 +.byte (1 << 2)
1.706 +.byte (1 << 2)
1.707 +.byte (1 << 2)
1.708 +.byte (1 << 2)
1.709 +.byte (1 << 2)
1.710 +.byte (1 << 2)
1.711 +.byte (1 << 2)
1.712 +.byte (1 << 2)
1.713 +.byte (1 << 2)
1.714 +.byte (1 << 2)
1.715 +.byte (1 << 2)
1.716 +.byte (1 << 2)
1.717 +.byte (1 << 2)
1.718 +.byte (1 << 2)