Mercurial > public > mk2
view code_part1/OSTC_code_asm_part1/dump_screen.asm @ 512:e7893664bd29
BUGFIX Spurious stop order when simulating deadly fast ascent.
author | JeanDo |
---|---|
date | Sun, 04 Dec 2011 17:45:51 +0100 |
parents | 1b09cead63a8 |
children | 6e456a6398e0 |
line wrap: on
line source
;============================================================================= ; ; File dump_screen.asm ; ; Dump screen contains to the serial interface. ; ; This program is free software: you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program. If not, see <http://www.gnu.org/licenses/>. ; ; Copyright (c) 2011, JD Gascuel. ;============================================================================= ; HISTORY ; 2011-05-08 : [jDG] Creation. ; ; BUGS : ; * ... ;============================================================================= CBLOCK 0x000 ds_line ; Current line (0..239). ds_column ; Current columnx2 (0..159) ds_pixel:2 ; Current pixel color. ds_count ; Repetition count. ENDC ;============================================================================= ; Manage interface to the OSTC platform: dump_screen: bcf uart_dump_screen ; clear flag! movlw 'l' movwf TXREG ; Send command echo. bsf no_sensor_int ; No Sensor Interrupt bcf PIE1,RCIE ; no interrupt for UART bcf PIR1,RCIF ; clear flag bsf LED_blue ; LEDusb ON call rs232_wait_tx ; wait for UART call dump_screen_0 bcf no_sensor_int ; Restore Sensor Interrupt bcf LED_blue ; Clear led bcf LED_red ; Clear led bsf PIE1,RCIE ; Interrupt for RS232 return ;============================================================================= ; Dump screen contains to the UART dump_screen_0: ;---- Send OLED box command for the full screen window ------------------- mullw 0 ; PRODH:L <- 0 AA_CMD_WRITE 0x35 ; VerticalStartAddress HIGH:LOW AA_DATA_WRITE_PROD ; 00:00 AA_CMD_WRITE 0x36 ; VerticalEndAddress HIGH:LOW AA_DATA_WRITE 0x01 AA_DATA_WRITE 0x3F AA_CMD_WRITE 0x37 ; HorizontalAddress START:END AA_DATA_WRITE 0x00 AA_DATA_WRITE 0xEF btfss win_flip_screen ; OSTC 2N have a flipped screen, bra dump_screen_mk2 ; So we should start 239 instead. movlw LOW(.239) movwf PRODL movlw HIGH(.239) movwf PRODH dump_screen_mk2: AA_CMD_WRITE 0x20 ; Start Address Horizontal (.0 - .239) AA_DATA_WRITE_PROD ; 00:00 mullw 0 ; Make sure PROD is 0 again. AA_CMD_WRITE 0x21 ; Start Address Vertical (.0 - .319) AA_DATA_WRITE_PROD ; 00:00 AA_CMD_WRITE 0x22 ; Start reading. rcall PLED_DataRead ; Dummy pixel to skip. rcall PLED_DataRead ; Dummy pixel to skip. movlw .160 ; 160x2 columns movwf ds_column rcall dump_screen_pixel_reset dump_screen_1: btg LED_red ; LEDactivity toggle AA_CMD_WRITE 0x22 ; Re-sync data. setf TRISD ; PortD as input. ; Dump even column movlw .240 ; 240 lines, once. movwf ds_line dump_screen_2: rcall PLED_DataRead ; read pixel-high byte movwf PRODH rcall PLED_DataRead ; read pixel-low byte movwf PRODL rcall dump_screen_pixel decfsz ds_line,F bra dump_screen_2 rcall dump_screen_pixel_flush ; Dump odd column movlw .240 ; 240 lines, twice. movwf ds_line dump_screen_3: rcall PLED_DataRead ; read pixel-high byte movwf PRODH rcall PLED_DataRead ; read pixel-low byte movwf PRODL rcall dump_screen_pixel decfsz ds_line,F bra dump_screen_3 rcall dump_screen_pixel_flush clrf TRISD ; Back to normal (PortD as output) decfsz ds_column,F bra dump_screen_1 AA_CMD_WRITE 0x00 ; NOP, to stop Address Update Counter return ;============================================================================= ; Pixel compression ; ; Input: PRODH:L = pixel. ; Output: Compressed stream on output. ; Compressed format: ; 0ccccccc : BLACK pixel, repeated ccccccc+1 times (1..128). ; 11cccccc : WHITE pixel, repeated cccccc+1 times (1..64). ; 10cccccc HIGH LOW : color pixel (H:L) repeated ccccc+1 times (1..64). ; dump_screen_pixel: movf PRODH,W ; Compare pixel-high xorwf ds_pixel+1,W bnz dump_screen_pixel_1 ; Different -> dump. movf PRODL,W ; Compare pixel-low xorwf ds_pixel+0,W bnz dump_screen_pixel_1 ; Different -> dump. incf ds_count,F ; Same color: just increment. return dump_screen_pixel_1: ; Send (pixel,count) tuple movf ds_count,W ; Is count zero ? bz dump_screen_pixel_2 ; Yes: skip sending. movf ds_pixel+1,W ; This is a BLACK pixel ? iorwf ds_pixel+0,W bz dump_screen_pix_black ; YES. movf ds_pixel+1,W ; This is a white pixel ? andwf ds_pixel+0,W incf WREG bz dump_screen_pix_white ; YES. ; No: write the pixel itself... movlw .64 ; Max color pixel on a single byte. cpfsgt ds_count ; Skip if count > 64 movf ds_count,W ; W <- min(64,count) subwf ds_count,F ; ds_count <- ds_count-W decf WREG ; Save as 0..63 iorlw b'10000000' ; MARK as a color pixel. movwf TXREG call rs232_wait_tx ; wait for UART movff ds_pixel+1,TXREG call rs232_wait_tx ; wait for UART movff ds_pixel+0,TXREG call rs232_wait_tx ; wait for UART bra dump_screen_pixel_1 dump_screen_pixel_2: movff PRODH,ds_pixel+1 ; Save new pixel color movff PRODL,ds_pixel+0 movlw 1 movwf ds_count ; And set count=1. return dump_screen_pix_black: movlw .128 ; Max black pixel on a single byte. cpfsgt ds_count ; Skip if count > 128 movf ds_count,W ; W <- min(128,count) subwf ds_count,F ; ds_count <- ds_count-W decf WREG ; Save as 0..127 dump_screen_pix_3: movwf TXREG call rs232_wait_tx bra dump_screen_pixel_1 ; More to dump ? dump_screen_pix_white: movlw .64 ; Max white pixel on a single byte. cpfsgt ds_count ; Skip if count > 64 movf ds_count,W ; W <- min(64,count) subwf ds_count,F ; ds_count <- ds_count-W decf WREG ; Save as 0..63 iorlw b'11000000' ; MARK as a compressed white. bra dump_screen_pix_3 dump_screen_pixel_flush: clrf PRODH clrf PRODL rcall dump_screen_pixel_1 ; Send it dump_screen_pixel_reset: clrf ds_count ; But clear count. return