📄 main.asm
字号:
; Butterfly BASIC - a BASIC interpreter for the MSP430
; Copyright (c) 2003, 2004 Paul Curtis
; email: plc@rowley.co.uk
#include <msp430x44x.h>
#undef SIMULATOR
#define PLATFORM "SoftBaugh ES449"
BRKTEST macro EXITLABEL
bit.b #URXIFG0, &IFG1 ; is a key ready?
jz EXITLABEL ; ...no, continue execution
cmp.b #0x03, &RXBUF0 ; is the key the break key?
jne EXITLABEL ; ...no, continue execution
endm
#include "../interpreter.inc"
; The first address at which a program is stored.
; Make this a flash page boundary.
user_flash_begin equ 0x3000
.bss
lcd_field_3_cursor ds.b 1
.code
print_char_table:
dc.w uart_0_print_char
dc.w uart_1_print_char
dc.w lcd_field_3_print_char
print_at_table:
dc.w uart_0_print_at
dc.w uart_1_print_at
dc.w lcd_field_3_print_at
; Initialise hardware ready to roll.
hw_init:
; Configure crystal and timing system
bis.b #XCAP14PF, &FLL_CTL0 ; Configure load caps.
bis.b #FN_2, &SCFI0 ; x2 DCO, 4MHz nominal DCO
mov.b #121, &SCFQCTL ; (121+1) x 32768 ~= 4MHz
mov.b #SSEL1, &UTCTL0 ; UCLK = SMCLK
; Configure UART
mov.b #0x68, &UBR00 ; 38400 baud @ 4MHz
mov.b #0x00, &UBR10
mov.b #0x00, &UMCTL0 ; No modulation.
mov.b #CHAR, &UCTL0 ; 8-bit character *SWRST*
mov.b #UTXE0+URXE0, &ME1 ; Enable USART0 TXD/RXD.
bis.b #0x30, &P2SEL ; P2.4,5 = USART0 TXD/RXD.
bis.b #0x10, &P2DIR ; P2.4 output direction.
; Set up flash timing generator
mov.w #0xa54a, &FCTL2 ; FTG source is MCLK/11
; Wait for FLL to stabilize.
mov.w #10000, r15
fll_wait:
sub.w #1, r15
jnz fll_wait
mov.b #0x32, &P1SEL
mov.b #0xff, &P2SEL
mov.b #0xff, &P3SEL
mov.b #0xff, &P4SEL
mov.b #0xff, &P5SEL
bis.b #3, &P1DIR
mov.b #0, &P1OUT
mov.b #3, &P1OUT
; Set up LCD
mov.b #LCDSG0_7 | LCD4MUX | LCDSON | LCDON, &LCDCTL
; Set up basic timer for LCD
mov.b #BT_fLCD_DIV64 + 0x23, &BTCTL
call #display_clear
ret
// Starburst segment definitions.
#define _N 0x0001
#define _M 0x0002
#define _K 0x0004
#define _J 0x0008
#define _D 0x0010
#define _C 0x0020
#define _B 0x0040
#define _A 0x0080
#define _P 0x0100
#define _Q 0x0200
#define _G 0x0400
#define _H 0x0800
#define _E 0x2000
#define _F 0x4000
starburst_segments:
dw 0 /* */
dw _F | _E // Lame /*!*/
dw _H | _K /*"*/
dw _J | _B | _P | _C | _G | _M /*#*/
dw _A | _F | _G | _M | _C | _D | _J | _P /*$*/
dw 0 // No good idea /*%*/
dw 0 // No good idea /*&*/
dw _K /*'*/
dw _A | _F | _E | _D /*(*/
dw _A | _B | _C | _D /*)*/
dw _H | _J | _K | _G | _M | _Q | _P | _N /***/
dw _J | _G | _M | _P /*+*/
dw 0 // No good idea /*,*/
dw _G | _M /*-*/
dw 0 // Should use decimal point, but... /*.*/
dw _K | _Q /*/*/
dw _A | _B | _C | _D | _E | _F | _Q | _K /*0*/
dw _C | _B /*1*/
dw _A | _B | _M | _G | _E | _D /*2*/
dw _A | _B | _M | _G | _C | _D /*3*/
dw _F | _G | _M | _B | _C /*4*/
dw _A | _F | _G | _M | _C | _D /*5*/
dw _A | _F | _E | _D | _C | _M | _G /*6*/
dw _F | _A | _B | _C /*7*/
dw _A | _B | _C | _D | _E | _F | _G | _M /*8*/
dw _A | _F | _G | _M | _B | _C | _D /*9*/
dw 0 // No good idea /*:*/
dw 0 // No good idea /*;*/
dw _K | _N /*<*/
dw _G | _M | _D /*=*/
dw _H | _Q /*>*/
dw _A | _B | _M | _G | _E /*?*/
dw 0 // No good idea /*@*/
dw _E | _F | _A | _B | _C | _G | _M /*A*/
dw _A | _B | _C | _D | _J | _P | _M /*B*/
dw _A | _F | _E | _D /*C*/
dw _A | _B | _C | _D | _J | _P /*D*/
dw _A | _F | _E | _D | _G | _M /*E*/
dw _A | _F | _E | _G | _M /*F*/
dw _A | _F | _E | _D | _C | _M /*G*/
dw _F | _E | _G | _M | _B | _C /*H*/
dw _A | _J | _P | _D /*I*/
dw _B | _C | _D | _E /*J*/
dw _F | _E | _G | _K | _N /*K*/
dw _F | _E | _D /*L*/
dw _E | _F | _H | _K | _B | _C /*M*/
dw _E | _F | _H | _N | _C | _B /*N*/
dw _A | _B | _C | _D | _E | _F /*O*/
dw _E | _F | _A | _B | _G | _M /*P*/
dw _A | _B | _C | _D | _E | _F | _N /*Q*/
dw _E | _F | _A | _B | _G | _M | _N /*R*/
dw _A | _F | _G | _M | _C | _D /*S*/
dw _A | _J | _P /*T*/
dw _F | _E | _D | _C | _B /*U*/
dw _F | _E | _Q | _K /*V*/
dw _F | _E | _Q | _N | _C | _B /*W*/
dw _H | _K | _Q | _N /*X*/
dw _H | _K | _P /*Y*/
dw _A | _K | _Q | _D /*Z*/
uart_0_print_at:
ret
uart_0_print_char:
#if defined(SIMULATOR)
push.w r12
push.w r13
push.w r14
push.w r15
call #_debug_putchar
pop.w r15
pop.w r14
pop.w r13
pop.w r12
#else
print_char_00:
// bit.b #UTXIFG0, &IFG1
// jz print_char_00
cmp.b #0, &IFG1
jge print_char_00
mov.b r15, &TXBUF0
cmp.b #'\n', r15
jnz print_char_return
print_char_10:
// bit.b #UTXIFG0, &IFG1
// jz print_char_10
cmp.b #0, &IFG1
jge print_char_10
mov.b #'\r', &TXBUF0
print_char_return:
#endif
ret
uart_1_print_char:
ret
uart_1_print_at:
ret
get_char:
#if defined(SIMULATOR)
push.w r12
push.w r13
push.w r14
call #_debug_getchar
pop.w r14
pop.w r13
pop.w r12
ret
#else
get_char_00:
bit.b #URXIFG0, &IFG1
jz get_char_00
mov.b &RXBUF0, r15
cmp.b #'\r', r15
jnz get_char_return
mov.b #'\n', r15
#endif
get_char_return:
call #print_char
ret
; Clear the whole display
display_clear:
mov.b #0, &lcd_field_3_cursor
mov.w #19, r15
display_clear_10:
mov.b #0, LCDMEM(r15)
sub.w #1, r15
jc display_clear_10
ret
lcd_field_3_print_at:
mov.b r14, &lcd_field_3_cursor
ret
lcd_field_3_print_char:
push.w r14
push.w r15
cmp.w #'a', r15
jnc lcd_field_3_print_char_00
cmp.w #'z', r15
bic.w #0x20, r15
lcd_field_3_print_char_00:
cmp.w #0x0c, r15 ; clear screen?
jnz lcd_field_3_display_char_00
mov.w #19, r15
lcd_field_3_print_char_05:
mov.b #0, LCDMEM(r15)
sub.w #1, r15
jc lcd_field_3_print_char_05
jmp lcd_field_3_display_char_return
lcd_field_3_display_char_00:
cmp.w #'\n', r15
jnz lcd_field_3_display_char_10
mov.b #0, &lcd_field_3_cursor
jmp lcd_field_3_display_char_return
lcd_field_3_display_char_10:
cmp.b #7, &lcd_field_3_cursor ; come to end of field and need to scroll?
jnz lcd_field_3_display_char_30 ; no, just write the next character
sub.b #1, &lcd_field_3_cursor
mov.w #0x97+11, r14
lcd_field_3_display_char_20:
mov.w @r14, 2(r14)
sub.b #1, r14
cmp.w #0x97-1, r14
jnz lcd_field_3_display_char_20
lcd_field_3_display_char_30:
mov.w #0x97+12, r14
sub.b &lcd_field_3_cursor, r14
sub.b &lcd_field_3_cursor, r14
sub.w #' ', r15
add.w r15, r15
mov.w starburst_segments(r15), r15
mov.b r15, 0(r14)
swpb r15
mov.b r15, 1(r14)
add.b #1, &lcd_field_3_cursor
lcd_field_3_display_char_return:
pop.w r15
pop.w r14
ret
; DISPLAY [#n], ...
; DISPLAY CLEAR
x_display:
cmp.w #T_CLEAR, r4
jz x_display_clear
jmp x_print
x_display_clear:
call #display_clear
mov.b @tp+, r4
jmp term
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -