@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ @ Assembly file "message.s" @ @ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @---------------------------------------------------------------------- @ Part 1 @ Define peripheral I/O base and register offsets .equ PIO_base, 0xFFFF0000 @ Peripheral I/O base .equ PIO_OER, 0x10 @ Output enable register .equ PIO_ODR, 0x14 @ Output disable register .equ PIO_SODR, 0x30 @ Set output data register .equ PIO_CODR, 0x34 @ Clear output data register .equ PIO_PDSR, 0x3c @ Pin data status register .equ LCD_int_SW_delay, 100 .equ AT91_LCD_RS, 0x00800000 @ LCD register select .equ AT91_LCD_En, 0x01000000 @ LCD enable .equ AT91_LCD_RW, 0x02000000 @ LCD read/write .equ AT91_LCD_busy, 0x00000080 @ MSB of data bus @---------------------------------------------------------------------- @ Part 2 @ Define constants .equ TRUE, -1 .equ FALSE, 0 .equ cEOT, 4 .equ cLF, 10 .equ cFF, 12 .equ cCR, 13 .equ ttr, 0 @---------------------------------------------------------------------- @ Part 3 .text .global tuning @ Declare function tuning .global error @ Declare function error .global notauthorized @ Declare function notauthorized tuning: mov ip, sp @ Save the callers Stack pointer into ip stmfd sp!, {fp, ip, lr, pc, r0-r6} @ Store things that need to be preserved sub fp, ip, #4 @ Set up frame pointer ldr r0, =tuning_msg bl print_str_LCD tuning_done: @ldmfd sp!, {r0-r6, pc} ldmea fp, {fp, sp, pc, r0-r6} error: mov ip, sp @ Save the callers Stack pointer into ip stmfd sp!, {fp, ip, lr, pc, r0-r6} @ Store things that need to be preserved sub fp, ip, #4 @ Set up frame pointer ldr r0, =error_msg bl print_str_LCD error_done: @ldmfd sp!, {r0-r6, pc} ldmea fp, {fp, sp, pc, r0-r6} notauthorized: mov ip, sp @ Save the callers Stack pointer into ip stmfd sp!, {fp, ip, lr, pc, r0-r6} @ Store things that need to be preserved sub fp, ip, #4 @ Set up frame pointer ldr r0, =authorization_msg bl print_str_LCD notauthorized_done: @ldmfd sp!, {r0-r6, pc} ldmea fp, {fp, sp, pc, r0-r6} @---------------------------------------------------------------------- @ Part 4 print_str_LCD: stmfd sp!, {r0-r1,lr} mov r1, r0 @ String pointer print_str_LCD_1: ldrb r0, [r1], #1 @ Load, auto-increment cmp r0, #ttr @ Check for string terminator ldmeqfd sp!, {r0-r1,pc} @ Conditional return bl print_ch_LCD bl delay b print_str_LCD_1 print_ch_LCD: stmfd sp!, {lr} bl LCD_wtr @ Check if LCD is busy cmp r0, #cCR beq print_ctrl_ch1 cmp r0, #cFF beq print_ctrl_ch2 cmp r0, #cLF beq print_ctrl_ch3 bl LCD_data_wr @ Branch to LCD write @ function ldmfd sp!, {pc} print_ctrl_ch1: stmfd sp!, {r0} mov r0, #0x02 @ Home cursor bl LCD_ctrl_wr ldmfd sp!, {r0, pc} print_ctrl_ch2: stmfd sp!, {r0} mov r0, #0x01 @ Clear screen bl LCD_ctrl_wr ldmfd sp!, {r0, pc} print_ctrl_ch3: stmfd sp!, {r0} @ Swap text lines bl LCD_ctrl_rd @ Get current DDRAM address eor r0, r0, #0x40 @ Other line bic r0, r0, #0x3F @ at the start orr r0, r0, #0x80 @ Command bl LCD_ctrl_wr ldmfd sp!, {r0, pc} @---------------------------------------------------------------------- @ Part 5 LCD_wtr: stmfd sp!, {r0, r4, lr} ldr r4, =PIO_base mov r0, #AT91_LCD_RS @ Data bus defaults to input str r0, [r4, #PIO_CODR] @ Control register mov r0, #AT91_LCD_RW str r0, [r4, #PIO_SODR] @ Read mov r0, #AT91_LCD_En @ LCD Enable pin LCD_wtr1: str r0, [r4, #PIO_SODR] @ LCD Enable ldr r14, [r4, #PIO_PDSR] @ Read pin data str r0, [r4, #PIO_CODR] tst r14, #AT91_LCD_busy @ See if busy bne LCD_wtr1 @ Yes - keep trying ldmfd sp!, {r0, r4, pc} @---------------------------------------------------------------------- @ Part 6 LCD_data_wr: stmfd sp!, {r1, lr} @ Write R0 to LCD data register ldr r14, =PIO_base mov r1, #AT91_LCD_RS str r1, [r14, #PIO_SODR] @ Data register b LCD_wr @ Jump to write ... LCD_ctrl_wr: stmfd sp!, {r1, lr} @ Write R0 to LCD control register ldr r14, =PIO_base mov r1, #AT91_LCD_RS str r1, [r14, #PIO_CODR] @ Control register @ Fall into write LCD_wr: mov r1, #AT91_LCD_RW str r1, [r14, #PIO_CODR] @ Write mov r1, #0xFF str r1, [r14, #PIO_OER] @ Drive LCD data bus/enable output str r1, [r14, #PIO_CODR] str r0, [r14, #PIO_SODR] mov r1, #AT91_LCD_En str r1, [r14, #PIO_SODR] @ LCD Enable str r1, [r14, #PIO_CODR] mov r1, #0xFF str r1, [r14, #PIO_ODR] @ Disable the data outputs ldmfd sp!, {r1, pc} @---------------------------------------------------------------------- @ Part 7 LCD_ctrl_rd: stmfd sp!, {r1, lr} @ Read R0 from LCD control register ldr r14, =PIO_base mov r1, #AT91_LCD_RS str r1, [r14, #PIO_CODR] @ Control register b LCD_rd @ Jump to read ... LCD_rd: mov r1, #AT91_LCD_RW str r1, [r14, #PIO_SODR] @ Read mov r1, #0xFF str r1, [r14, #PIO_ODR] @ Float LCD data bus mov r1, #AT91_LCD_En str r1, [r14, #PIO_SODR] @ LCD Enable mov r0, #100 @ Each iteration ~100us (100ns ROM) LCD_rd_1: nop @ 5 instructions fetched/loop subs r0, r0, #1 bhi LCD_rd_1 ldr r0, [r14, #PIO_PDSR] @ Read pins str r1, [r14, #PIO_CODR] @ Remove LCD enable and r0, r0, #0xFF @ Mask off unwanted bits ldmfd sp!, {r1, pc} delay: mov r0, #2000 @ Each iteration ~100us (100ns ROM) add r0, r0, #2000 dly1: subs r0, r0, #1 @ 5 instructions fetched/loop movls pc, lr b dly1 @---------------------------------------------------------------------- @ Part 8 tuning_msg: .byte cFF .ascii " Tuning... DONE " .byte cLF .ascii " Enjoy the Show " .byte ttr error_msg: .byte cFF .ascii " No Signal Detected " .byte cLF .ascii " Try Another Channel" .byte ttr authorization_msg: .byte cFF .ascii " Not Authorized To " .byte cLF .ascii " Watch This Channel " .byte ttr @ @---------------------------------------------------------------------- .END