Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; bfsim 2.0
- ;
- ; robert@robos.org
- ; http://robos.org
- ;
- ; BrainFuck system for pic16f84a
- ;
- ; Original version by Robert Цstling, August 2003.
- ; Rewritten February 2004 - bug fixes. Lots of bug fixes.
- ;
- ; Note: Keep all the tables far away from any 256 words boundaries.
- ;
- ; Instructions:
- ;
- ; + 00 Increase value at pointer by one.
- ; - 01 Decrease value at pointer by one.
- ; > 02 Increase pointer by one.
- ; < 03 Decrease pointer by one.
- ; [ 04 Jump to next ]
- ; ] 05 Jump to previous [ unless value at pointer is zero.
- ; . 06 Output value at pointer to portb.
- ; , 07 Input value from porta (bits 1 to 3) and store to pointer.
- ;
- ; Program memory - 128 instructions (64 bytes) of EEPROM.
- ; RAM memory - 32 bytes (0x20 to 0x3f).
- ; Stack - 16 bytes (0x40 to 0x4f).
- ;
- ; I/O:
- ;
- ; porta0 - "enter" key.
- ; porta1 - porta3 - Input value (0 to 7).
- ; portb - Output (LEDs).
- ;
- ; 10000001 on the LEDs means: Input command.
- ; 11000011 on the LEDs means: Input data to user program.
- list p=PIC16F84A
- include "p16f84a.inc"
- cblock 0x0c
- iptr,ptr,sptr,cptr,nest,tmp
- endc
- page
- __config _CP_OFF & _LP_OSC & _PWRTE_ON & _WDT_OFF
- org 0
- reset:
- bcf intcon,gie ; disable interrupts
- call initialize ; initialize vars, mem, i/o
- main_loop:
- movlw 0x81
- movwf portb ; output 10000001 to portb
- call input
- clrf portb
- movfw tmp ; w = command
- andlw 0x03
- addwf pcl ; execute command from keyboard:
- goto cmd_00 ; input opcode
- goto cmd_01 ; reset program pointer
- goto cmd_02 ; "backspace"
- goto cmd_03 ; run program
- ; input opcode
- cmd_00:
- call input ; input byte to tmp
- movfw cptr
- incf cptr
- movwf eeadr ; eeadr = cptr++
- call nibble_write ; write to eeprom
- goto main_loop
- ; reset program pointer
- cmd_01:
- clrf cptr
- goto main_loop
- ; "backspace"
- cmd_02:
- decf cptr
- goto main_loop
- ; run program
- cmd_03:
- clrf iptr
- cmd_03_loop:
- call execute
- incf iptr
- goto cmd_03_loop
- ; execute one instruction
- execute:
- movfw iptr
- movwf eeadr ; read instruction from iptr
- call nibble_read
- addwf pcl ; execute instruction
- goto instr_00 ; +
- goto instr_01 ; -
- goto instr_02 ; >
- goto instr_03 ; <
- goto instr_04 ; [
- goto instr_05 ; ]
- goto instr_06 ; .
- goto instr_07 ; ,
- ; +
- instr_00:
- movfw ptr
- addlw 0x20
- movwf fsr ; point to current memory location
- incf indf ; increase it
- return
- ; -
- instr_01:
- movfw ptr
- addlw 0x20
- movwf fsr ; point to current memory location
- decf indf ; decrease it
- return
- ; >
- instr_02:
- incf ptr
- movlw 0x1f
- andwf ptr ; ptr = (ptr + 1) mod 0x20
- return
- ; <
- instr_03:
- decf ptr
- movlw 0x1f
- andwf ptr ; ptr = (ptr - 1) mod 0x20
- return
- ; [
- instr_04:
- incf iptr ; iptr++
- decf sptr
- movfw sptr
- movwf fsr
- movfw iptr
- movwf indf ; push iptr to stack
- movlw 0x01
- movwf nest ; nest = 1
- decf iptr ; now let's find the next ] instruction
- instr_04_find:
- incf iptr
- movfw iptr
- movwf eeadr
- call nibble_read ; read nest instruction
- sublw 0x05 ; is it "]" ?
- bz instr_04_end
- sublw 0x01 ; is it "[" ?
- btfsc status,z
- incf nest ; yes, increase nest
- goto instr_04_find
- instr_04_end:
- decf nest
- bnz instr_04_find ; if --nest != 0, continue
- decf iptr ; iptr--
- return ; otherwise return to normal execution
- ; ]
- instr_05:
- movfw ptr
- addlw 0x20
- movwf fsr
- movfw indf ; get value at current memory location
- sublw 0x00
- bnz instr_05_loop ; is it 0?
- incf sptr
- return ; yes, drop value on stack and continue.
- instr_05_loop:
- movfw sptr
- movwf fsr
- movfw indf
- movwf iptr ; iptr = top of stack, don't change sptr
- decf iptr ; iptr--
- return ; continue execution
- ; .
- instr_06:
- movfw ptr
- addlw 0x20
- movwf fsr
- movfw indf
- movwf portb ; output value on current memory location to portb
- call input_wait ; wait for "enter" key
- return
- ; ,
- instr_07:
- movlw 0xc3
- movwf portb ; output 11000011 to portb
- movfw ptr
- addlw 0x20
- movwf fsr ; point to current memory location
- call input ; read byte from keyboard
- movfw tmp
- movwf indf ; store to memory
- clrf portb ; clear portb
- return
- input:
- call input_wait ; wait for "enter" key
- movfw porta
- andlw 0x0e
- movwf tmp
- bcf status,c
- rrf tmp ; tmp = (byte >> 1) mod 8
- return
- input_wait:
- btfss porta,0
- goto input_wait ; wait for "enter" key
- clrf tmp
- input_wait1:
- incf tmp
- btfss tmp,3
- goto input_wait1 ; short delay
- input_wait2:
- btfsc porta,0
- goto input_wait2 ; wait for "enter" key to release
- return
- ; read nibble addressed by eeadr to w
- nibble_read:
- btfsc eeadr,0
- goto nibble_read_odd ; check if we're reading an odd nibble
- bcf status,c
- rrf eeadr ; eeadr = eeadr / 2
- call eeprom_read
- movfw eedata ; read byte to w
- andlw 0x0f ; mask out high 4 bits
- return
- nibble_read_odd:
- bcf status,c
- rrf eeadr ; eeadr = eeadr / 2
- call eeprom_read
- swapf eedata ; swap high and low nibble
- movfw eedata
- andlw 0x0f ; mask out high 4 bits
- return
- ; read byte from eeadr to eedata
- eeprom_read:
- bsf status,rp0
- bsf eecon1,rd
- bcf status,rp0
- return
- ; write the nibble in tmp to the address in eeadr
- nibble_write:
- bcf status,c
- rrf eeadr ; eeadr = eeadr / 2
- bc nibble_write_odd ; check if we're writing to an odd nibble
- call eeprom_read
- movfw eedata ; read byte
- andlw 0xf0 ; mask out low nibble
- addwf tmp,w ; fill it with our data
- goto nibble_write_done
- nibble_write_odd:
- call eeprom_read
- movfw eedata ; read byte
- andlw 0x0f ; mask out high nibble
- swapf tmp
- addwf tmp,w ; fill it with out data
- nibble_write_done:
- movwf eedata
- ; write the byte on eedata to the address in eeadr
- eeprom_write:
- bsf status,rp0
- bsf eecon1,wren
- movlw 0x55
- movwf eecon2
- movlw 0xaa
- movwf eecon2
- bsf eecon1,wr
- bcf status,rp0
- return
- initialize:
- clrf porta
- clrf portb
- bsf status,rp0
- movlw 0x1f
- movwf trisa ; set porta to input mode
- clrf trisb ; set portb to output mode
- bcf status,rp0
- movlw 0x01
- movwf portb
- demo_loop:
- bcf status,c
- rlf portb ; portb = portb << 1
- btfsc status,c ; did we shift out the bit?
- incf portb ; yes, set portb to 1 again
- clrf tmp
- demo_delay:
- decfsz tmp
- goto demo_delay ; 10ms delay
- btfss porta,0
- goto demo_loop ; if "enter" key is not pressed, loop
- call input_wait ; wait for its release
- clrf portb
- clrf iptr
- clrf ptr
- movlw 0x50
- movwf sptr
- clrf cptr
- movlw 0x20
- movwf fsr
- clear_ram:
- clrf indf
- incf fsr
- btfss fsr,6
- goto clear_ram
- return
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement