babusha

Untitled

Nov 7th, 2011
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; bfsim 2.0
  2. ;
  3. ; http://robos.org
  4. ;
  5. ; BrainFuck system for pic16f84a
  6. ;
  7. ; Original version by Robert Цstling, August 2003.
  8. ; Rewritten February 2004 - bug fixes. Lots of bug fixes.
  9. ;
  10. ; Note: Keep all the tables far away from any 256 words boundaries.
  11. ;
  12. ; Instructions:
  13. ;
  14. ; +  00  Increase value at pointer by one.
  15. ; -  01  Decrease value at pointer by one.
  16. ; >  02  Increase pointer by one.
  17. ; <  03  Decrease pointer by one.
  18. ; [  04  Jump to next ]
  19. ; ]  05  Jump to previous [ unless value at pointer is zero.
  20. ; .  06  Output value at pointer to portb.
  21. ; ,  07  Input value from porta (bits 1 to 3) and store to pointer.
  22. ;
  23. ; Program memory    - 128 instructions (64 bytes) of EEPROM.
  24. ; RAM memory        - 32 bytes (0x20 to 0x3f).
  25. ; Stack         - 16 bytes (0x40 to 0x4f).
  26. ;
  27. ; I/O:
  28. ;
  29. ; porta0        - "enter" key.
  30. ; porta1 - porta3   - Input value (0 to 7).
  31. ; portb         - Output (LEDs).
  32. ;
  33. ; 10000001 on the LEDs means: Input command.
  34. ; 11000011 on the LEDs means: Input data to user program.
  35.  
  36.  
  37.     list    p=PIC16F84A
  38.     include "p16f84a.inc"
  39.  
  40.     cblock 0x0c
  41.     iptr,ptr,sptr,cptr,nest,tmp
  42.     endc
  43.  
  44.     page
  45.     __config _CP_OFF & _LP_OSC & _PWRTE_ON & _WDT_OFF
  46.  
  47.     org 0
  48.  
  49. reset:
  50.     bcf intcon,gie      ; disable interrupts
  51.     call    initialize      ; initialize vars, mem, i/o
  52.  
  53. main_loop:
  54.     movlw   0x81
  55.     movwf   portb           ; output 10000001 to portb
  56.     call    input
  57.     clrf    portb
  58.     movfw   tmp         ; w = command
  59.     andlw   0x03
  60.  
  61.     addwf   pcl         ; execute command from keyboard:
  62.     goto    cmd_00          ; input opcode
  63.     goto    cmd_01          ; reset program pointer
  64.     goto    cmd_02          ; "backspace"
  65.     goto    cmd_03          ; run program
  66.  
  67. ; input opcode
  68. cmd_00:
  69.     call    input           ; input byte to tmp
  70.     movfw   cptr
  71.     incf    cptr
  72.     movwf   eeadr           ; eeadr = cptr++
  73.     call    nibble_write        ; write to eeprom
  74.     goto    main_loop
  75.  
  76. ; reset program pointer
  77. cmd_01:
  78.     clrf    cptr
  79.     goto    main_loop
  80.  
  81. ; "backspace"
  82. cmd_02:
  83.     decf    cptr
  84.     goto    main_loop
  85.  
  86. ; run program
  87. cmd_03:
  88.     clrf    iptr
  89. cmd_03_loop:
  90.     call    execute
  91.     incf    iptr
  92.     goto    cmd_03_loop
  93.  
  94. ; execute one instruction
  95. execute:
  96.     movfw   iptr
  97.     movwf   eeadr           ; read instruction from iptr
  98.     call    nibble_read
  99.  
  100.     addwf   pcl         ; execute instruction
  101.     goto    instr_00        ; +
  102.     goto    instr_01        ; -
  103.     goto    instr_02        ; >
  104.     goto    instr_03        ; <
  105.     goto    instr_04        ; [
  106.     goto    instr_05        ; ]
  107.     goto    instr_06        ; .
  108.     goto    instr_07        ; ,
  109.  
  110. ; +
  111. instr_00:
  112.     movfw   ptr
  113.     addlw   0x20
  114.     movwf   fsr         ; point to current memory location
  115.     incf    indf            ; increase it
  116.     return
  117.  
  118. ; -
  119. instr_01:
  120.     movfw   ptr
  121.     addlw   0x20
  122.     movwf   fsr         ; point to current memory location
  123.     decf    indf            ; decrease it
  124.     return
  125.  
  126. ; >
  127. instr_02:
  128.     incf    ptr
  129.     movlw   0x1f
  130.     andwf   ptr         ; ptr = (ptr + 1) mod 0x20
  131.     return
  132.  
  133. ; <
  134. instr_03:
  135.     decf    ptr
  136.     movlw   0x1f
  137.     andwf   ptr         ; ptr = (ptr - 1) mod 0x20
  138.     return
  139.  
  140. ; [
  141. instr_04:
  142.     incf    iptr            ; iptr++
  143.     decf    sptr
  144.     movfw   sptr
  145.     movwf   fsr
  146.     movfw   iptr
  147.     movwf   indf            ; push iptr to stack
  148.     movlw   0x01
  149.     movwf   nest            ; nest = 1
  150.     decf    iptr            ; now let's find the next ] instruction
  151. instr_04_find:
  152.     incf    iptr
  153.     movfw   iptr
  154.     movwf   eeadr
  155.     call    nibble_read     ; read nest instruction
  156.     sublw   0x05            ; is it "]" ?
  157.     bz  instr_04_end
  158.     sublw   0x01            ; is it "[" ?
  159.     btfsc   status,z
  160.     incf    nest            ; yes, increase nest
  161.     goto    instr_04_find  
  162. instr_04_end:
  163.     decf    nest
  164.     bnz instr_04_find       ; if --nest != 0, continue
  165.     decf    iptr            ; iptr--
  166.     return              ; otherwise return to normal execution
  167.  
  168. ; ]
  169. instr_05:
  170.     movfw   ptr
  171.     addlw   0x20
  172.     movwf   fsr
  173.     movfw   indf            ; get value at current memory location
  174.     sublw   0x00
  175.     bnz instr_05_loop       ; is it 0?
  176.     incf    sptr
  177.     return              ; yes, drop value on stack and continue.
  178. instr_05_loop:
  179.     movfw   sptr
  180.     movwf   fsr
  181.     movfw   indf
  182.     movwf   iptr            ; iptr = top of stack, don't change sptr
  183.     decf    iptr            ; iptr--
  184.     return              ; continue execution
  185.  
  186. ; .
  187. instr_06:
  188.     movfw   ptr
  189.     addlw   0x20
  190.     movwf   fsr
  191.     movfw   indf
  192.     movwf   portb           ; output value on current memory location to portb
  193.     call    input_wait      ; wait for "enter" key
  194.     return
  195.  
  196. ; ,
  197. instr_07:
  198.     movlw   0xc3
  199.     movwf   portb           ; output 11000011 to portb
  200.     movfw   ptr
  201.     addlw   0x20
  202.     movwf   fsr         ; point to current memory location
  203.     call    input           ; read byte from keyboard
  204.     movfw   tmp
  205.     movwf   indf            ; store to memory
  206.     clrf    portb           ; clear portb
  207.     return
  208.  
  209. input:
  210.     call    input_wait      ; wait for "enter" key
  211.     movfw   porta
  212.     andlw   0x0e
  213.     movwf   tmp
  214.     bcf status,c
  215.     rrf tmp         ; tmp = (byte >> 1) mod 8
  216.     return
  217.  
  218. input_wait:
  219.     btfss   porta,0
  220.     goto    input_wait      ; wait for "enter" key
  221.     clrf    tmp
  222. input_wait1:
  223.     incf    tmp
  224.     btfss   tmp,3
  225.     goto    input_wait1     ; short delay
  226. input_wait2:
  227.     btfsc   porta,0
  228.     goto    input_wait2     ; wait for "enter" key to release
  229.     return
  230.  
  231. ; read nibble addressed by eeadr to w
  232. nibble_read:
  233.     btfsc   eeadr,0
  234.     goto    nibble_read_odd     ; check if we're reading an odd nibble
  235.     bcf status,c
  236.     rrf eeadr           ; eeadr = eeadr / 2
  237.     call    eeprom_read
  238.     movfw   eedata          ; read byte to w
  239.     andlw   0x0f            ; mask out high 4 bits
  240.     return
  241. nibble_read_odd:
  242.     bcf status,c
  243.     rrf eeadr           ; eeadr = eeadr / 2
  244.     call    eeprom_read
  245.     swapf   eedata          ; swap high and low nibble
  246.     movfw   eedata
  247.     andlw   0x0f            ; mask out high 4 bits
  248.     return
  249.  
  250. ; read byte from eeadr to eedata
  251. eeprom_read:
  252.     bsf status,rp0
  253.     bsf eecon1,rd
  254.     bcf status,rp0
  255.     return
  256.  
  257. ; write the nibble in tmp to the address in eeadr
  258. nibble_write:
  259.     bcf status,c
  260.     rrf eeadr           ; eeadr = eeadr / 2
  261.     bc  nibble_write_odd    ; check if we're writing to an odd nibble
  262.     call    eeprom_read
  263.     movfw   eedata          ; read byte
  264.     andlw   0xf0            ; mask out low nibble
  265.     addwf   tmp,w           ; fill it with our data
  266.     goto    nibble_write_done
  267. nibble_write_odd:
  268.     call    eeprom_read
  269.     movfw   eedata          ; read byte
  270.     andlw   0x0f            ; mask out high nibble
  271.     swapf   tmp
  272.     addwf   tmp,w           ; fill it with out data
  273. nibble_write_done:
  274.     movwf   eedata
  275.  
  276. ; write the byte on eedata to the address in eeadr
  277. eeprom_write:
  278.     bsf status,rp0
  279.     bsf eecon1,wren
  280.     movlw   0x55
  281.     movwf   eecon2
  282.     movlw   0xaa
  283.     movwf   eecon2
  284.     bsf eecon1,wr
  285.     bcf status,rp0
  286.     return
  287.  
  288. initialize:
  289.     clrf    porta
  290.     clrf    portb
  291.     bsf status,rp0
  292.     movlw   0x1f
  293.     movwf   trisa           ; set porta to input mode
  294.     clrf    trisb           ; set portb to output mode
  295.     bcf status,rp0
  296.  
  297.     movlw   0x01
  298.     movwf   portb
  299. demo_loop:
  300.     bcf status,c
  301.     rlf portb           ; portb = portb << 1
  302.     btfsc   status,c        ; did we shift out the bit?
  303.     incf    portb           ; yes, set portb to 1 again
  304.     clrf    tmp
  305. demo_delay:
  306.     decfsz  tmp
  307.     goto    demo_delay      ; 10ms delay
  308.     btfss   porta,0
  309.     goto    demo_loop       ; if "enter" key is not pressed, loop
  310.     call    input_wait      ; wait for its release
  311.  
  312.     clrf    portb
  313.     clrf    iptr
  314.     clrf    ptr
  315.     movlw   0x50
  316.     movwf   sptr
  317.     clrf    cptr
  318.     movlw   0x20
  319.     movwf   fsr
  320.  
  321. clear_ram:
  322.     clrf    indf
  323.     incf    fsr
  324.     btfss   fsr,6
  325.     goto    clear_ram
  326.  
  327.     return
  328.  
  329.     end
  330.  
  331.  
Advertisement
Add Comment
Please, Sign In to add comment