prjbrook

forth85_24A. Tried Notepad++, avrasm2

Aug 15th, 2014
376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 73.28 KB | None | 0 0
  1. ;this is forth85_24A Tidies up forth85_24. Trying Notpad++ rather that avr studio 4
  2. ;Changed to Notepad++ and comand line asm. Having issues with rcall CR. Sends '\' sometimes
  3. ;Nearly live. Probs with $0d on input line. Solved. Don't do st -x,r16 then st x+,r16.
  4. ;do and test BRANCH and 0 BRANCH NOT DONE
  5. ; Also calcjump for rjmp opcodes needs tsting. NOT DONE
  6. ;could try (begin .... again) loop. Kind of dione. Needs live run
  7. .NOLIST
  8. .include "tn85def.inc"
  9. .LIST
  10. ;.LISTMAC ;sometimes macro code gets in way of clarity in listing
  11. .MACRO header
  12. .db high(@0), low(@0), @1, @2
  13. .ENDMACRO
  14. .MACRO mypop
  15. ld @0,-y
  16. .ENDMACRO
  17. .MACRO mypush
  18. st y+, @0
  19. .ENDMACRO
  20. .MACRO mypop2
  21. mypop @0
  22. mypop @1
  23. .ENDMACRO
  24. .MACRO mypush2
  25. mypush @0
  26. mypush @1
  27. .ENDMACRO
  28. .MACRO pushx
  29. push xl
  30. push xh
  31. .ENDMACRO
  32. .MACRO popx
  33. pop xh
  34. pop xl
  35. .ENDMACRO
  36. .MACRO pushz
  37. push zl
  38. push zh
  39. .ENDMACRO
  40. .MACRO popz
  41. pop zh
  42. pop zl
  43. .ENDMACRO
  44. .MACRO mypopa ;call r16,17 the accumulator a, ditto for r18,r19 for b
  45. mypop r17
  46. mypop r16
  47. .ENDMACRO
  48. .MACRO mypopb
  49. mypop2 r19,r18
  50. .ENDMACRO
  51. .macro TAKEMEOUT
  52. ldi serialByteReg, @0
  53. rcall sendSerialByte
  54. ldi serialByteReg, @0
  55. rcall sendSerialByte
  56.  
  57. .endmacro
  58.  
  59.  
  60.  
  61.  
  62. .def mylatest =r2 ;r2,r3 is mylatest
  63. .def myhere =r4 ;r4,r5 is myhere. The pointer to flash copy in buf2.
  64. .def SOFPG=r6 ;start of flash page
  65. ;r6,r7 byte adr of flash page (11c0)
  66. ;r8,r9 (0012) offset when flash comes into buf2. r8 +E0 = myhere
  67. .def SECONDLETTER =r10 ;helpful for debugging
  68. .def FOUNDCOUNTER = r11 ;dealWithWord clicks this if found =1. Counts successful finds in dictionary.
  69. .def STATE = r12
  70. .def STOP = r13 ;stop interpreting line of words
  71. .def BOTTOM = r14 ;have hit the bottom of the dict and not found a match
  72. .def FOUND = r15 ;if found=1 we have a match of Ram word on dictionary
  73. .def spmcsr_val=r18
  74. .def buf_ctr =r19 ;for flash section
  75. ;r20 is length of word in WORD
  76. ;r21 is the flash length of word with immediate bit 8, if any, still there
  77.  
  78. .def vl = r22
  79. .def vh = r23 ; u,v,w,x,y,z are all pointers
  80. .def wl = r24 ;w=r24,25
  81. .def wh = r25
  82.  
  83. .equ TX_PIN = 0
  84. .equ RX_PIN = 2 ; Tx,Rx pins are PB0 and PB2 resp
  85.  
  86. .def serialByteReg = r16
  87. .def rxByte = r18
  88. .def counterReg = r17
  89.  
  90. ;.equ testing = 1 ;makes io verbose. comment out later
  91.  
  92.  
  93. .eseg
  94. .org $10
  95. .dw HERE, LATEST ;these should be burned into tn85 with code
  96.  
  97. .DSEG
  98. .ORG 0x60
  99.  
  100. .equ BUF1LENGTH = 128
  101. .equ eHERE = $0010 ;eeprom adr of system varial eHere
  102. .equ eLATEST = $0012
  103.  
  104. buf1: .byte BUF1LENGTH ;input buffer. Lines max about 125
  105. buf2: .byte BUF1LENGTH ;this fits two flash buffers
  106. varSpace: .byte 64 ;might need more than 32 variables
  107. myStackStart: .byte 64 ;currently at $1E0.Meets return stack.
  108.  
  109. .CSEG
  110. .ORG 0x800 ;dictionary starts at 4K (2K words) mark
  111. ;----------------------------------------------------
  112. one_1:
  113. .db 0,0,3, "one" ;code for one
  114. one:
  115. ; rcall stackme
  116. rcall stackme_2
  117. .db 01, 00
  118. ret
  119. ;----------------------------------------------
  120. two_1:
  121. header one_1, 3, "two"
  122. two:
  123. rcall stackme_2
  124. .db 02,00
  125. ret
  126. ;------------------------------------------
  127. dup_1:
  128. header two_1,3,"dup"
  129. dup:
  130. mypop r17
  131. mypop r16
  132. mypush r16
  133. mypush r17
  134. mypush r16
  135. mypush r17
  136.  
  137. ret
  138. ;-------------------------------------------
  139. drop_1:
  140. header dup_1,4,"drop"
  141. drop:
  142. mypop r17
  143. mypop r16 ;TODO what if stack pointer goes thru floor?
  144. ret
  145. ;----------------------------------
  146. swapp_1: ;twp p's becasue assembler recognizes avr opcode swap
  147. header drop_1,5, "swapp"
  148. swapp:
  149. mypop2 r17,r16
  150. mypop2 r19,r18
  151. mypush2 r16,r17
  152. mypush2 r18,r19
  153. ret
  154.  
  155.  
  156. ;-------------------------------------------------
  157. ;shift this later
  158.  
  159. S_1:
  160. ;the EOL token that gets put into end of buf1 to stop parsing
  161. header swapp_1,$81,"S" ;NB always immediate
  162. S: ldi r16,02
  163. mov BOTTOM,r16 ;r14 =2 means a nice stop. EOL without errors
  164. clr STOP
  165. inc STOP ;set time-to-quit flag
  166. ret
  167. ;------------------------------------------
  168.  
  169. fetch_1: ;doesn't like label = @-1
  170. ;classic fetch. (adr -- num). Only in RAM
  171. header S_1,1,"@"
  172. fetch:
  173. pushx ;going to use x to point so better save
  174. mypop xh
  175. mypop xl
  176. ld r16,x+
  177. ld r17,x
  178. mypush r16
  179. mypush r17 ; and put them on my stack
  180. popx ;return with x intact and RAM val on my stack
  181. ret
  182. ;dddddddddddddddddddddddddddddddddddddddddddddddd
  183.  
  184. cfetch_1: ;doesn't like label = c@-1
  185. ;classic fetch. (adr -- num). Only in RAM. Do I want y to advance just one byte on mystack
  186. header fetch_1,2,"c@"
  187. cfetch:
  188. pushx ;going to use x to point so better save
  189. mypop xh
  190. mypop xl
  191. ld r16,x+
  192. mypush r16
  193. popx ;return with x intact and RAM val on my stack
  194. ret
  195. ;dddddddddddddddddddddddddddddddddddddddddddddddd
  196.  
  197. store_1: ;classic != "store"(adr num --) . Num is now at cell adr.
  198. header cfetch_1,1,"!"
  199. store:
  200. mypop2 r17,r16 ;there goes the num
  201. pushx
  202. mypop2 xh,xl ;there goes the address
  203. st x+,r16
  204. st x,r17 ;num goes to cell with location=adr
  205. popx
  206. ret
  207. ;ddddddddddddddddddddddddddddddddddddddddddddddddddd
  208.  
  209. cstore_1: ;classic c!= "store"(adr 8-bitnum --) . 8 bit Num is now at cell adr.
  210. header store_1,2,"c!"
  211. cstore:
  212. mypop r16 ;there goes the num. Just 8 bits at this stage.
  213. pushx
  214. mypop2 xh,xl ;there goes the address
  215. st x+,r16
  216. ; st x,r17 ;num goes to cell with location=adr
  217. popx
  218. ret
  219. ;------------------------------------
  220.  
  221. star_1: ;classic 16*16 mulitply (n n -- n*n)
  222. header cstore_1,1,"*"
  223. star:
  224. mypop2 r17,r16
  225. mypop2 r19,r18 ;now have both numbers in r16..r19
  226. rcall mpy16s ; multiply them. Result in r18..r21. Overflow in r20,21
  227. mypush2 r18,r19
  228. ret
  229. ;-----------------------------------------
  230.  
  231. slashMod_1: ;classic /MOD (n m -- n/m rem)
  232. header star_1,4,"/mod"
  233. slashMod:
  234. push r13
  235. push r14 ;this is STOP but is used by div16s, so better save it
  236. mypop2 r19,r18 ; that's m
  237. mypop2 r17,r16 ;that's n
  238. rcall div16s ;the the 16 by 16 bit divsion
  239. mypush2 r16,r17 ;answer ie n/m
  240. mypush2 r14,r15 ;remainder
  241. pop r14
  242. pop r13
  243. ret
  244. ;dddddddddddddddddddddddddddddddddddddddddddd
  245.  
  246. plus_1: ;classic + ( n n -- n+n)
  247. header slashMod_1,1,"+"
  248. plus:
  249. mypop2 r17,r16
  250. mypop2 r19,r18
  251. clc
  252. add r16,r18
  253. adc r17,r19
  254. mypush2 r16,r17
  255. ret
  256. ;--
  257.  
  258. minus_1: ;classic - ( n m -- n-m)
  259. header plus_1,1,"-"
  260. minus:
  261. mypop2 r19,r18
  262. mypop2 r17,r16
  263. clc
  264. sub r16,r18
  265. sbc r17,r19
  266. mypush2 r16,r17
  267. ret
  268. ;dddddddddddddddddddddddddddddddddddddddddd
  269.  
  270. pstore_1: ;expects eg. 0003 PORTB P! etc, "output 3 via PORTB"
  271. header minus_1,2, "p!"
  272. pstore:
  273. mypopb ;get rid of PORTB number, not used for tiny85, just one port
  274. mypopa ; this is used. it's eg the 003 = R16 above
  275. out PORTB,r16
  276. ret
  277. ;ddddddddddddddddddddddddd
  278.  
  279. portblabel_1:
  280. header pstore_1,5,"PORTB" ; note caps just a filler that point 0b in stack for dropping
  281. portblabel:
  282. ; Extend later on to include perhaps other ports
  283. ; one:
  284. ; rcall stackme
  285.  
  286. rcall stackme_2
  287. .db $0b, 00
  288. ret
  289. ;---------------------
  290.  
  291. datadirstore_1: ;set ddrb. invioked like this 000f PORTB dd! to make pb0..pb3 all outputs
  292. header portblabel_1, 3, "dd!"
  293. datadirstore:
  294. mypopb ; there goes useless 0b = PORTB
  295. mypopa ; 000f now in r17:16
  296. out DDRB,r16
  297. ret
  298. ;dddddddddddddddddddddddddddddddddddd
  299. ;sbilabel_1 ;set bit in PORTB. Just a kludge at this stage
  300. ;header datadirstore_1,3,"sbi" TODO sort out sbi and delay later. Now get on with compiler.
  301. ;first need store system vars in the eeprom. Arbitrarily 0010 is HERE and 0012 (in eeprom) is LATEST
  302. ;----------------------------------------
  303.  
  304. percentcstore_1: ;(n16 adr16 --) %c! stores stack val LSbyte to eeprom adr
  305. ; eg 10 00 1234 stores 34 to 0010 <--eeprom adr
  306. header datadirstore_1,3,"%c!"
  307. percentcstore:
  308. mypopb ;adr in r18,19
  309. mypopa ;data. Lower byte into r16
  310.  
  311. rcall eewritebyte ;burn it into eeprom
  312. ret
  313. ;----------------------------------
  314.  
  315. percentstore_1: ; (n16 adr16 --) b16 stored at eeprom adr adr16 and adr16+1
  316. header percentcstore_1,2, "%!"
  317. percentstore:
  318. mypopb ;adr in b=r18,19
  319. mypopa ;n16 into r16,17 as data
  320.  
  321. rcall eewritebyte ;burn low data byte
  322. clc
  323. inc r18
  324. brne outpcs
  325. inc r17 ;sets up adr+1 for next byte
  326. outpcs:
  327. mov r16,r17 ;r16 now conatins hi byte
  328. rcall eewritebyte
  329. ret
  330. ;-------------------------------
  331.  
  332. percentcfetch_1: ;(eepromadr16--char). Fetch eeprom byte at adr on stack
  333. header percentstore_1,3,"%c@"
  334. percentcfetch:
  335. mypopb ;adr now in r18,19
  336. rcall eereadbyte
  337. mypush r16 ; there's the char going on stack. Should be n16? Not n8?
  338. ret
  339. ;-------------------
  340.  
  341. percentfetch_1: ;(adr16--n16) get 16bits at adr and adr+1
  342. header percentcfetch_1,2,"%@"
  343. percentfetch:
  344. rcall percentcfetch ;low byte now on stack
  345. inc r18
  346. brcc downpf
  347. inc r19
  348. downpf:
  349. rcall eereadbyte ;there's the high byte hitting the mystack
  350. mypush r16
  351. ret
  352. ;-------------------------------
  353. gethere_1: ; leaves current value of eHERE on stack
  354. header percentfetch_1,7,"gethere"
  355. gethere:
  356. rcall stackme_2
  357. .dw eHere
  358. rcall percentfetch
  359. ret
  360. ;--------------------
  361.  
  362. getlatest_1: ;leaves current value of latest on stack
  363. header gethere_1,9, "getlatest"
  364. getlatest:
  365. rcall stackme_2
  366. .dw eLATEST ;the address of the latest link lives in eeprom at address 0012
  367. rcall percentfetch ;get the val out of eeprom
  368. ret
  369. ;------------------
  370.  
  371. colon_1: ;classic ":"compiling new word marker
  372. header getlatest_1,1,":"
  373. rcall coloncode
  374. ret
  375. ;----------------------------------------
  376.  
  377. comma_1: ;classic comma. ;Put adr on stack into dictionary at myhere and bump myhere
  378. header colon_1,1,","
  379. comma:
  380. mypopa ;adr now in r16,17
  381. pushz ;save z
  382. movw zl,myhere ;z now pnts to next avail space in dic
  383. st z+,r16
  384. st z+,r17
  385. movw myhere,zl ;so that myhere is updated as ptr
  386. popz ;bring z back
  387. ret
  388. ;------------------------------------
  389.  
  390. tic_1: ;clasic tic('). Put cfa of next word on stack
  391. header comma_1,1, "'"
  392. tic:
  393. rcall word ;point to next word in input
  394. rcall findword ;leaving cfa in z
  395. mypush2 zl,zh
  396. rcall two ;but it's in bytes. Need words so / by 2
  397. rcall slashmod
  398. rcall drop ;that's the remainder dropped
  399. ;now have cfa of word after ' on stack in word-units.
  400. ret
  401. ;-----------------------
  402.  
  403. dummy_1: ;handy debugging place to put a break point
  404. header tic_1,$85,"dummy" ;first immediate word
  405. dummy:
  406. nop
  407. ret
  408. ;--------------------------------
  409.  
  410. compstackme_2_1: ;needed infront of every number compiled
  411. header dummy_1, $0d,"compstackme_2"
  412. compstackme_2:
  413. ldi r16,low(stackme_2)
  414. ldi r17,high(stackme_2)
  415. mypush2 r16,r17 ;in words need to *2 to convert to bytes
  416. rcall two
  417. rcall star
  418. rcall compileme
  419. ret
  420. ;-----------------------------------------
  421.  
  422. double_1: ;whatever's on stack gets doubled. Usful words-->bytes. (n...2*n)
  423. header compstackme_2_1, 6, "double"
  424. double:
  425. mypopa ;stk to r16,17
  426. clc ;going to do shifts
  427. rol r16
  428. rol r17 ;r16,17 now doubled
  429. mypush2 r16,r17
  430. ret ;with 2*n on my stk
  431. ;--------------------------------------
  432.  
  433. semi_1: ;classic ";". Immediate TODO compile a final ret
  434. header double_1,$81,";"
  435. semi:
  436. nop
  437. rcall insertret ;compile ret
  438. rcall burnbuf2and3
  439. rcall rbrac ;after semi w'got back to executing
  440. ; rcall updatevars ;update HERE and LATEST in eeprom
  441. rcall updatevars2 ;Better version. update HERE and LATEST in eeprom
  442.  
  443. ret
  444. ;---------------------------------------
  445.  
  446. rbrac_1: ;classic "]" ,immediate
  447. header semi_1,$81,"]"
  448. rbrac:
  449. clr STATE ;go to executing
  450. ret
  451. ;------------------------------------------------
  452.  
  453. immediate_1: ;classic IMMEDIATE. Redo len byte so MSbit =1
  454. header rbrac_1,$89,"immediate"
  455. immediate:
  456. mypush2 r2,r3 ;this is mylatest. pnts to link of new word
  457. rcall two
  458. rcall plus ;jmp over link to pnt to len byte
  459. pushx ;better save x
  460. mypop2 xh,xl ;x now pnts to len byte
  461. ld r16,x ; and put it into r6
  462. ldi r18,$80 ;mask
  463. or r16,r18 ;eg 03 --> 83 in hex
  464. st x,r16 ;put len byte back
  465. popx ;back where it was
  466. ret ;done now newly created word is immediate
  467. ;-------------------------------------------------
  468.  
  469. emit_1: ;(n8 --) classic emit
  470.  
  471. header immediate_1, 4, "emit"
  472. emit:
  473. rcall emitcode
  474. ret
  475. ;--------------------------------------
  476.  
  477. getline_1: ;rx a line of chars from serialin. eol = $0d
  478. ;this is the line that gets interpreted
  479. header emit_1,7, "getline"
  480. getline:
  481. rcall rxStrEndCR ;write 64 TODO 128? bytes into buf1 from serial io
  482. .ifdef testing
  483. rcall dumpbuf1
  484. .endif
  485. ret ;with buf1 ready to interpret
  486. ;-------------------------------------------------
  487.  
  488. zero_1: ;stack a zero
  489. header getline_1,4,"zero"
  490. zero:
  491. rcall stackme_2
  492. .db 0,0
  493. ret
  494. ;----------------------------------------
  495.  
  496. equal_1: ;(n1 n2 -- flag)
  497. header zero_1,1,"="
  498. equal:
  499. rcall equalcode
  500. ret
  501. ;----------------------------------------
  502.  
  503. zeroequal_1: ;(n -- flag)
  504. header equal_1,2,"0="
  505. zeroequal:
  506. rcall zero
  507. rcall equal
  508. ret
  509. ;-------------------------
  510.  
  511. over_1: ;(n1 n2 --n1 n2 n1)
  512. header zero_1,4,"over"
  513. over:
  514. mypopa
  515. mypopb
  516. mypush2 r18,r19 ;n1
  517. mypush2 r16,r17 ;n2
  518. mypush2 r18,r19 ;n1. so end up with (n1,n2,n1
  519. ret
  520. ;-----------------------------------
  521.  
  522. rot_1: ;classic (n1 n2 n3 -- n2 n3 n1)
  523. header over_1,3,"rot"
  524. rot:
  525. mypopa
  526. push r17
  527. push r16 ;save n3
  528. rcall swapp ; n2 n1
  529. pop r16
  530. pop r17
  531. mypush2 r16,r17 ;n2 n1 n3
  532. rcall swapp ;n2 n3 n1
  533. ret
  534. ;------------------------------------
  535.  
  536. reverse3_1: ;PB (n1 n2 n3 -- n3 n2 n1). Reverses top 3 order
  537. header rot_1,8,"reverse3"
  538. reverse3:
  539. rcall swapp ; n1 n3 n2
  540. rcall rot ; n3 n2 n1
  541. ret ;so (n1 n2 n3 -- n3 n2 n1)
  542. ;--------------------------------------------
  543.  
  544. unrot_1: ;PB (n1 n2 n3 -- n3 n1 n2) Buries topitem two down
  545. header reverse3_1,5,"unrot"
  546. unrot:
  547. rcall reverse3 ; (n1 n2 n3 -- n3 n2 n1)
  548. rcall swapp ; n3 n1 n2
  549. ret
  550. ;--------------------------------
  551.  
  552. andd_1: ;classic AND
  553. header unrot_1,4,"andd" ; two d's otherwise asm problems
  554. andd:
  555. mypopa
  556. mypopb
  557. and r16,r18
  558. and r17,r19
  559. mypush2 r16,r17
  560. ret
  561. ;----------------------------------------
  562.  
  563.  
  564. orr_1: ;classic OR
  565. header andd_1,3,"orr" ; two r's otherwise asm problems
  566. orr:
  567. mypopa
  568. mypopb
  569. or r16,r18
  570. or r17,r19
  571. mypush2 r16,r17
  572. ret
  573. ;------------------------
  574.  
  575. calcjump_1: ;(to from -- opcode)
  576. header orr_1,$88, "calcjump"
  577. calcjump:
  578. rcall calcjumpcode
  579. ret ;with opcode on stack
  580. ;-----------------------
  581.  
  582. begin_1: ;( -- adr) classic BEGIN. Used in most loops
  583. header calcjump_1,$85,"begin"
  584. begin:
  585. rcall stackmyhere ;put next adr on stack. For AGAIN etc
  586. ret ;with adr on stack
  587. ;---------------------------
  588. again_1: ; (to_adr -- ) classic AGAIN cts loop back to BEGIN
  589. header begin_1, $85,"again"
  590. rcall stackmyhere ; to_adr fr_adr
  591. rcall minus ;rel_adr_distance eg $ffdd
  592. rcall stackme_2
  593. .dw $0002
  594. rcall div ;now adr difference in words. Works better.
  595. rcall stackme_2
  596. .dw $0fff ;$ffdd $0fff
  597. rcall andd ;$0fdd eg.
  598. rcall stackme_2
  599. .dw $c000 ;$0fdd $c000
  600. rcall orr ;$cffdd = rjmp back_to_again
  601. rcall one
  602. rcall minus ;t0-fr-1 = the jump part of rjmp
  603. rcall comma ;insert into dic
  604. ret ;with rjmp opcode in next pos in dic
  605. ;------------------------------
  606.  
  607. div_1: ; (n1 n2 -- n1/n2) classic / Could make 2 / faster with >, one right shift
  608. header again_1,1,"/"
  609. div:
  610. rcall slashMod
  611. rcall drop
  612. ret
  613. ;---------------------------------
  614.  
  615. halve_1: ; (n -- n/2) use shifts to halve num on stack. Handy
  616. header div_1,5,"halve"
  617. halve:
  618. mypopa
  619. clc
  620. ror r17
  621. ror r16
  622. mypush2 r16,r17 ;now num on stack has been halved
  623. ret ;with n/2 on stk
  624. ;--------------------
  625.  
  626. dumpb1_1: ;dumpbuf1 to serial
  627. header halve_1,6,"dumpb1"
  628. dumpb1:
  629. rcall dumpbuf1
  630. ret
  631. ;---------------------
  632.  
  633. OK_1: ;classic "ok"
  634. header dumpb1_1,2,"OK"
  635. OK:
  636. ldi r16,'K'
  637. ldi r17,'O'
  638. mypush2 r16,r17
  639. rcall emitcode
  640. rcall emitcode
  641. ldi r16,'}' ;try this for a cursor prompt
  642. mypush r16
  643. rcall emitcode
  644.  
  645. ret ;after having emitted "OK" to terminal
  646. ;-------------------------------
  647.  
  648. CR_1: ;output a carriage return. Need $0d too?
  649. header OK_1,2, "CR"
  650. CR:
  651. ldi r16,$0d
  652. mypush r16
  653. rcall emitcode
  654. ret ;after sending CR to terminal
  655. ;--------------------------
  656. LATEST:
  657. test1_1: ;just need some dic word to try with new serialFill
  658. header CR_1,5,"test1"
  659. test1:
  660. ldi serialByteReg, '*'
  661. rcall sendSerialByte
  662. ldi serialByteReg, '*'
  663. rcall sendSerialByte
  664. ldi serialByteReg, '*'
  665. rcall sendSerialByte
  666. ldi serialByteReg, '*'
  667. rcall sendSerialByte
  668. ret
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684. ;-----------------------------------------------
  685. HERE:
  686. .db "444444444444444444444444444444"
  687. rcall stackme_2
  688. .dw $1234
  689. rcall two
  690. rcall stackme_2
  691. .dw $2468
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711. ;---------------stackme_2 used to live here----------------------------------
  712.  
  713.  
  714.  
  715.  
  716. ;====================================================================================================
  717.  
  718. .ORG 0
  719. rjmp quit
  720. ; rjmp mainloop
  721. ; rjmp start
  722. ;typein: .db "11bb 0014 %! getlatest",$0d, "0013 %@",0x0d
  723. typein: .db "dumpb1", $0d
  724. ;typein: .db " : qqq one two dup one ; qqq " ,$0d
  725. ;"11bb 0014 %! ", $0d ;%! getlatest",$0d, "0013 %@",0x0d
  726. ;" one 0010 00ab %c! 0012 cdef %! 0013 %c@ 0013 %@ 0987 drop ", 0x0d
  727.  
  728. ;stackme dropx onex stackme swap drop",0x0d
  729. ;-----------------------------------------------------
  730. ;start:
  731. quit:
  732. ldi r16, low(RAMEND)
  733. out SPL, r16
  734.  
  735.  
  736. ldi r16,high(RAMEND)
  737. out SPH, r16
  738.  
  739. ldi YL,low(myStackStart)
  740. ldi YH,high(myStackStart)
  741. ldi r16, 0xf9 ;PORTB setup
  742. out DDRB,r16 ;
  743. nop
  744. ldi r16, $ff
  745. out PORTB,r16
  746. .IFDEF testing ;testing = simulating on avrstudio4
  747. nop
  748. rcall burneepromvars
  749.  
  750. .ENDIF
  751. forthloop:
  752. ldi r16, low(RAMEND)
  753. out SPL, r16
  754.  
  755.  
  756. ldi r16,high(RAMEND)
  757. out SPH, r16
  758.  
  759. ldi YL,low(myStackStart)
  760. ldi YH,high(myStackStart)
  761.  
  762. try:
  763. ;--------------------test these------------------
  764. ;rcall dumpbuf1
  765. ;rcall test_dumpbuf1
  766. ;rcall waitForDDump
  767. ;rjmp testOKCR
  768. ;rjmp test_rxStrEndCR
  769. ;rcall test1
  770. ;rjmp test_d16
  771. ;rjmp test_d1617
  772. ;rjmp test_dlowR
  773. ;rjmp test_dhighR
  774. rjmp test_dxyz
  775. ;rjmp try
  776. .ifdef testing
  777. rcall getline0 ;This is FORTH
  778. .else
  779. rcall serialFill
  780. .endif
  781. ;TODO work out why this isn't working with test1
  782. rcall dumpbuf1 ;TAKE OUT
  783. rcall interpretLine
  784. rcall dumpbuf1
  785. .ifdef testing
  786. nop
  787. quithere:
  788. rjmp quithere ;only want one line interpreted when testing
  789. .else
  790. rjmp forthloop
  791. .endif
  792. ;-------------------------------------------------------
  793.  
  794.  
  795. ;rjmp test_interpretLine
  796. ;rjmp test_cfetch
  797. ;rjmp test_store
  798. ;rjmp test_cstore
  799. ;rjmp test_mpy16s
  800. ;rjmp test_mpy16s0
  801. ;rjmp test_star
  802. ;rjmp test_div16s
  803. ;rjmp test_slashMod
  804. ;rjmp test_Hex4ToBin2
  805. rjmp test_interpretLine
  806. ;rjmp setupforflashin
  807. ;rcall coloncode
  808. ;rjmp test_buf2ToFlashBuffer
  809. ;rjmp serialTest0
  810. ;zzz
  811.  
  812. stopper: rjmp stopper
  813. ; rjmp start
  814. ;mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
  815. mainloop: ;this is forth. This is run continuously. Needs two versions: live and simulation.
  816. ; rcall quit
  817. rcall getline0
  818. rcall interpretLine
  819. ret
  820. ;--------------------------------------------------------------
  821. getline0: ;force a line into buf1 via flash string. Simulates GETLINE
  822. ldi zl, low(typein<<1)
  823. ldi zh, high(typein<<1)
  824. ldi xl, low(buf1)
  825. ldi xh, high(buf1)
  826. type0:
  827. lpm r16,Z+
  828. st x+,r16
  829. cpi r16,0x0d ;have we got to the end of the line?
  830. brne type0
  831. ret
  832. ;--------------------------------------------
  833. ;WORD gets x to point to start of word (copy in w=r24,25) with the length in len = r20
  834. ;assume word points to somewhere in buf1. Should advance thru spaces=0x20 to first real char
  835. word: ;maybe give it a header later
  836. ld SECONDLETTER, x ;for debugging. TODO. Should be firstletter?
  837.  
  838. ld r16,x+ ;get char
  839.  
  840. cpi r16,0x20 ;is it a space?
  841. breq word ;if so get next char
  842. ;if here we're point to word start. so save this adr in w
  843. mov r24,xl
  844. mov r25,xh ;wordstart now saved in w
  845.  
  846.  
  847. clr r20 ;length initially 0
  848. nextchar:
  849. inc r20 ;r20 = word length
  850. ld r16,x+ ;get next char
  851. cpi r16,0x20
  852. brne nextchar
  853. dec r24 ;adjust start of word
  854. ;if here we've found a word.Starting at w length in r20.x points to space just past word
  855. ret
  856. ;----------------------------------------
  857.  
  858. compare: ;given a word in buf1 and a word in the dic are they the same? The word in the dic is pointed to by Z.
  859. ; and the word in buf1 is pointed to by w=r24,25. len = r20. Z on entry points to the link. Needs +2 to
  860. lpm r23,z+
  861. lpm r22,z+ ;store next link in v=r22,23. z now points to len byte
  862.  
  863. startc:
  864. ;TODO save copy of flash word in r21 and also do masking of immediates
  865. push r20 ;save length
  866. lpm r16,Z+ ;length of dictionary word, first entry now in r16
  867. mov r21,r16 ;copy length-in-flash to r21. May have immediate bit (bit 7)
  868. andi r16,$0f ;mask off top nibble before comparing
  869. cp r16,r20 ;same lengths?
  870. brne outcom ;not = so bail out
  871. ;if here the words are the same length, what about the rest of the chars.First get x to point to word.
  872. mov xl,r24
  873. mov xh,r25 ;x now point to start of buf1 word
  874. upcom:
  875. lpm r16,z+
  876. ld r17,x+ ;get one corresponding char from each word
  877. cp r16,r17 ;same word?
  878. brne outcom ;bail out if chars are different
  879. dec r20 ;count chars
  880. brne upcom ;still matching and not finished so keep going
  881. ;if here r20 is 0 so match must have been perfect so FOUND = 1
  882. clr FOUND
  883. inc FOUND
  884. outcom:
  885. pop r20 ;get old lngth of buf1 word back
  886. ret
  887. ;-------------------------------------------
  888. jmpNextWord: ;go to next word in the dictionary. Assume v=r22,23 contains next link word(not byte)
  889. ; and w = r24,25 contains RAM word start with len in r20
  890. ;exit with z pointing to next word ready for next COMPARE.
  891. clc
  892. rol r22
  893. rol r23 ;above 3 instructions change word address into byte address by doubling
  894. movw r30,r22 ;z now points to next word
  895. ret
  896. ;-----------------------------------------
  897.  
  898. doLatest: ;set up so first jump in dictionary is to top=LATEST and other flags set up.
  899. ; ldi vl, low(LATEST)
  900. ; ldi vh, high(LATEST)
  901. nop
  902. rcall getlatest ;from eeprom. Now on stack
  903. mypop2 vh,vl ;this is in bytes Need to halve it.
  904. ; rcall halve
  905. clr FOUND
  906. clr BOTTOM ;not yet found the match, not yet at the bottom. Either will stop search.
  907. clr STOP ;keep parsing words til this goes to a 1
  908. ret
  909. ;---------------------------------------------
  910. interpretLine: ;given line of words in buf one, search for words one by one. Don't do code
  911. ; or compile at this stage, just find and report that and go into next one.
  912. ; rcall getline0 ;change later to real getline via terminal
  913.  
  914. rcall pasteEOL
  915. takemeout '2'
  916.  
  917. ldi xl, low(buf1)
  918. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  919. clr FOUNDCOUNTER ;counts finds in line parsing.
  920.  
  921. nextWord:
  922. tst STOP
  923. takemeout '4'
  924. brne stopLine
  925. rcall word
  926. takemeout '!'
  927. rcall findWord
  928. takemeout '5'
  929. ;not done yet
  930. rcall dealWithWord ;go and run code STATE=0, or compile (STATE =1).{ c0de, comp1le}
  931. rjmp nextWord
  932. stopLine:
  933. takemeout 'E'
  934. ret
  935. ;-----------------------------------------------------------------
  936. findWord:
  937. rcall doLatest
  938. nop
  939. rcall dumpbuf1
  940.  
  941. upjmpf:
  942. rcall jmpNextWord
  943. takemeout '6'
  944.  
  945. rcall compare
  946. tst FOUND
  947. brne stopsearchf ;if last compare got a match (FOUND=1) then stop searching
  948. tst vl
  949. brne upjmpf ;if v=0000 then we've hit the bottom of the dictionary
  950. tst vh
  951. brne upjmpf ;not found and not at bottom so keep going
  952. ;if here FOUND =0, ie no match yet and we've hit the bottom of the dictionary
  953. clr BOTTOM
  954. inc BOTTOM ;exit with FOUND=0 and BOTTOM =1
  955. stopsearchf:
  956. nop
  957. ret
  958. ;----------------------------
  959. test_interpretLine:
  960. rcall interpretLine
  961. til: rjmp til ;** with r24 pointing to 'S' and FOUND = r15 =1
  962. ;------------------------------
  963. dealWithWord: ;come here when it's time to compile or run code
  964. ;Good debugging spot. Enter here with Z pointing to CFA of word found. Y points to myStack. X points to just
  965. ; past the word we are seeking (w-s). r10 is 2nd letter of w-s. w = start adr of w-s. v is a link
  966. ; to the next word in dic. Either just below the found word or 0000 if we get to the bottome with no match
  967. ;
  968. nop
  969. tst FOUND
  970. breq notfound
  971. inc FOUNDCOUNTER
  972.  
  973. ;want to hop over filler bytes,0's added to keep codes on even byte boundaries
  974. ; so if r30 is odd at this stage inc it. odd is lsbit = 1.
  975. sbrs r30,0 ;skip next instruction if final bit lsb = 1
  976. rjmp downd
  977. ;if here lsb = 1 so we're on a padding byte and have to add 1 to get to a 2 byte boundary
  978. inc r30
  979. brcc downd
  980. inc r31 ;add one to z before converting to bytes
  981. ;have to ask at this point, is the word immediate? If so, bit 7 of r21 will be set.
  982. downd:
  983. sbrs r21,7
  984. rjmp downdw ;not immediate so just go on with STATE test
  985. rjmp executeme ;yes, immediate so execute every time.
  986.  
  987.  
  988. downdw: tst STATE
  989. breq executeme
  990. rcall compilecode
  991. rjmp outdww
  992. executeme:
  993. clc
  994. ror zh
  995. ror zl ;put z back into word values
  996.  
  997.  
  998. rcall executeCode
  999.  
  1000.  
  1001.  
  1002. .MESSAGE "Word found"
  1003. rjmp outdww
  1004. notfound:
  1005. nop
  1006. ; .MESSAGE "Word not found"
  1007. ; clr STOP
  1008. ; inc STOP ;stop parsing line
  1009. rcall numberh ; word not in dict so must be a number? Form = HHHH
  1010. ;now have to add 3 to x so it points past this word ready not next one
  1011. clc
  1012. inc r26
  1013. inc r26
  1014. inc r26
  1015. brcc outdww
  1016. inc r27 ;but only if overflow
  1017. nop
  1018. outdww:
  1019. ret ;with STOP =1 in not a number
  1020. ;------------------------------------------------------------------------
  1021. pasteEOL: ;when a line of text is TYPEd into buf1 it should end with CR=$0d. This gets replaced with ]}, a
  1022. ; special end of line word. When the word is invoked it casues a QUIT back to the waiting for input stage.
  1023. ; Start at buf1 start and inspect each char for a $0D. When found replace with a "$20 S $20 "
  1024.  
  1025. ldi xl, low(buf1)
  1026. ldi xh, high(buf1) ;pnt to start of buffer
  1027. clr r17
  1028. nxtChar:
  1029. inc r17 ;r17 is counter. Bail out when r17 > BUF1LENGTH
  1030. cpi r17, BUF1LENGTH -3
  1031. breq outProb
  1032. ld r16, x+
  1033. cpi r16, $0d
  1034. brne nxtChar
  1035. ;if here we've found a $0d in buf1 before the end, so replace with an EOL token. x points to just after it.
  1036. ldi r16,$20
  1037. st -x, r16 ;back up. Then go forward.
  1038. TAKEMEOUT '3'
  1039. ; ldi r16, ']'
  1040. ldi r16,$20 ;This took about 4 day's work to insert this line. Why is it needed?
  1041. st x+, r16
  1042. ldi r16,'S'
  1043. st x+, r16
  1044. ; ldi r16, '}'
  1045. ; st x+, r16
  1046. ldi r16, $20
  1047. st x, r16
  1048. rjmp outpel
  1049.  
  1050.  
  1051. outProb:
  1052. takemeout 'O'
  1053. nop
  1054. .MESSAGE "Couldn't find $0d"
  1055. outpel:
  1056. ret
  1057.  
  1058. ;-------------------------------------
  1059. executeCode: ;with Z pointing to cfa. Not sure whether to jmp or call
  1060.  
  1061. ijmp
  1062. ret
  1063. ;---------------------------------------
  1064. test_fetch: ;do run thru of @
  1065. rcall getline0 ;change later to real getline via terminal
  1066. rcall pasteEOL
  1067. ldi xl, low(buf1)
  1068. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  1069.  
  1070. ldi r16,$62
  1071. mypush r16
  1072. ldi r16,$0
  1073. mypush r16 ;should now have adr $0062 on mystack
  1074. rcall fetch
  1075. tf1:
  1076. rjmp tf1
  1077. ;---------------------------------
  1078. test_cfetch: ;do run thru of @
  1079. rcall getline0 ;change later to real getline via terminal
  1080. rcall pasteEOL
  1081. ldi xl, low(buf1)
  1082. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  1083.  
  1084. ldi r16,$62
  1085. mypush r16
  1086. ldi r16,$0
  1087. mypush r16 ;should now have adr $62 on mystack
  1088. rcall cfetch
  1089. tcf1:
  1090. rjmp tcf1
  1091. ;----------------------------
  1092. test_store:
  1093. rcall getline0 ;change later to real getline via terminal
  1094. rcall pasteEOL
  1095. ldi xl, low(buf1)
  1096. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  1097. ldi r16,$62
  1098. ldi r17,$0
  1099. mypush2 r16,r17 ;should now have adr $62 on mystack
  1100. ldi r16, $AB
  1101. ldi r17, $CD
  1102. mypush2 r16,r17 ;now have $ABCD on mystack
  1103. rcall store
  1104. ts1:
  1105. rjmp ts1
  1106. ;------------------------
  1107. test_cstore:
  1108. rcall getline0 ;change later to real getline via terminal
  1109. rcall pasteEOL
  1110. ldi xl, low(buf1)
  1111. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  1112. ldi r16,$62
  1113. ldi r17,$0
  1114. mypush2 r16,r17 ;should now have adr $62 on mystack
  1115. ldi r16, $AB
  1116. ; ldi r17, $CD
  1117. mypush r16 ;now have $ABCD on mystack
  1118. rcall cstore
  1119.  
  1120. ts11:
  1121. rjmp ts11
  1122. ;Now put arith routines here. Are from AVR200. Just using 16*16 for * but get 32bit result.
  1123.  
  1124.  
  1125. ;***************************************************************************
  1126. ;*
  1127. ;* "mpy16s" - 16x16 Bit Signed Multiplication
  1128. ;*
  1129. ;* This subroutine multiplies signed the two 16-bit register variables
  1130. ;* mp16sH:mp16sL and mc16sH:mc16sL.
  1131. ;* The result is placed in m16s3:m16s2:m16s1:m16s0.
  1132. ;* The routine is an implementation of Booth's algorithm. If all 32 bits
  1133. ;* in the result are needed, avoid calling the routine with
  1134. ;* -32768 ($8000) as multiplicand
  1135. ;*
  1136. ;* Number of words :16 + return
  1137. ;* Number of cycles :210/226 (Min/Max) + return
  1138. ;* Low registers used :None
  1139. ;* High registers used :7 (mp16sL,mp16sH,mc16sL/m16s0,mc16sH/m16s1,
  1140. ;* m16s2,m16s3,mcnt16s)
  1141. ;*
  1142. ;***************************************************************************
  1143.  
  1144. ;***** Subroutine Register Variables
  1145.  
  1146. .def mc16sL =r16 ;multiplicand low byte
  1147. .def mc16sH =r17 ;multiplicand high byte
  1148. .def mp16sL =r18 ;multiplier low byte
  1149. .def mp16sH =r19 ;multiplier high byte
  1150. .def m16s0 =r18 ;result byte 0 (LSB)
  1151. .def m16s1 =r19 ;result byte 1
  1152. .def m16s2 =r20 ;result byte 2
  1153. .def m16s3 =r21 ;result byte 3 (MSB)
  1154. .def mcnt16s =r22 ;loop counter
  1155.  
  1156. ;***** Code
  1157. mpy16s: clr m16s3 ;clear result byte 3
  1158. sub m16s2,m16s2 ;clear result byte 2 and carry
  1159. ldi mcnt16s,16 ;init loop counter
  1160. m16s_1: brcc m16s_2 ;if carry (previous bit) set
  1161. add m16s2,mc16sL ; add multiplicand Low to result byte 2
  1162. adc m16s3,mc16sH ; add multiplicand High to result byte 3
  1163. m16s_2: sbrc mp16sL,0 ;if current bit set
  1164. sub m16s2,mc16sL ; sub multiplicand Low from result byte 2
  1165. sbrc mp16sL,0 ;if current bit set
  1166. sbc m16s3,mc16sH ; sub multiplicand High from result byte 3
  1167. asr m16s3 ;shift right result and multiplier
  1168. ror m16s2
  1169. ror m16s1
  1170. ror m16s0
  1171. dec mcnt16s ;decrement counter
  1172. brne m16s_1 ;if not done, loop more
  1173. ret
  1174. ;----------------------------------------------------------
  1175. ;***** Multiply Two Signed 16-Bit Numbers (-12345*(-4321))
  1176. test_mpy16s:
  1177. ldi mc16sL,low(-12345)
  1178. ldi mc16sH,high(-12345)
  1179. ldi mp16sL,low(-4321)
  1180. ldi mp16sH,high(-4321)
  1181. rcall mpy16s ;result: m16s3:m16s2:m16s1:m16s0
  1182. ;=$032df219 (53,342,745)
  1183. tmpy: rjmp tmpy
  1184.  
  1185. test_mpy16s0:
  1186. ldi mc16sL,low(123)
  1187. ldi mc16sH,high(123)
  1188. ldi mp16sL,low(147)
  1189. ldi mp16sH,high(147)
  1190. rcall mpy16s ;result: m16s3:m16s2:m16s1:m16s0
  1191. tmpy0: rjmp tmpy0
  1192. ;-----------------------
  1193. test_star:
  1194. ldi r16,-$7b
  1195. mypush r16
  1196. ldi r16,$00
  1197. mypush r16 ;that's decimal 123 on stack
  1198. ldi r16,$93
  1199. mypush r16
  1200. ldi r16,$00
  1201. mypush r16 ; and thats dec'147
  1202. rcall star
  1203. tsr: rjmp tsr
  1204.  
  1205. ;--------------------------
  1206. ;***************************************************************************
  1207. ;*
  1208. ;* "div16s" - 16/16 Bit Signed Division
  1209. ;*
  1210. ;* This subroutine divides signed the two 16 bit numbers
  1211. ;* "dd16sH:dd16sL" (dividend) and "dv16sH:dv16sL" (divisor).
  1212. ;* The result is placed in "dres16sH:dres16sL" and the remainder in
  1213. ;* "drem16sH:drem16sL".
  1214. ;*
  1215. ;* Number of words :39
  1216. ;* Number of cycles :247/263 (Min/Max)
  1217. ;* Low registers used :3 (d16s,drem16sL,drem16sH)
  1218. ;* High registers used :7 (dres16sL/dd16sL,dres16sH/dd16sH,dv16sL,dv16sH,
  1219. ;* dcnt16sH)
  1220. ;*
  1221. ;***************************************************************************
  1222.  
  1223. ;***** Subroutine Register Variables
  1224.  
  1225. .def d16s =r13 ;sign register
  1226. .def drem16sL=r14 ;remainder low byte
  1227. .def drem16sH=r15 ;remainder high byte
  1228. .def dres16sL=r16 ;result low byte
  1229. .def dres16sH=r17 ;result high byte
  1230. .def dd16sL =r16 ;dividend low byte
  1231. .def dd16sH =r17 ;dividend high byte
  1232. .def dv16sL =r18 ;divisor low byte
  1233. .def dv16sH =r19 ;divisor high byte
  1234. .def dcnt16s =r20 ;loop counter
  1235.  
  1236. ;***** Code
  1237.  
  1238. div16s: ;push r13 ;PB !!
  1239. ;push r14 ;PB !!
  1240. mov d16s,dd16sH ;move dividend High to sign register
  1241. eor d16s,dv16sH ;xor divisor High with sign register
  1242. sbrs dd16sH,7 ;if MSB in dividend set
  1243. rjmp d16s_1
  1244. com dd16sH ; change sign of dividend
  1245. com dd16sL
  1246. subi dd16sL,low(-1)
  1247. sbci dd16sL,high(-1)
  1248. d16s_1: sbrs dv16sH,7 ;if MSB in divisor set
  1249. rjmp d16s_2
  1250. com dv16sH ; change sign of divisor
  1251. com dv16sL
  1252. subi dv16sL,low(-1)
  1253. sbci dv16sL,high(-1)
  1254. d16s_2: clr drem16sL ;clear remainder Low byte
  1255. sub drem16sH,drem16sH;clear remainder High byte and carry
  1256. ldi dcnt16s,17 ;init loop counter
  1257.  
  1258. d16s_3: rol dd16sL ;shift left dividend
  1259. rol dd16sH
  1260. dec dcnt16s ;decrement counter
  1261. brne d16s_5 ;if done
  1262. sbrs d16s,7 ; if MSB in sign register set
  1263. rjmp d16s_4
  1264. com dres16sH ; change sign of result
  1265. com dres16sL
  1266. subi dres16sL,low(-1)
  1267. sbci dres16sH,high(-1)
  1268. d16s_4: ;pop r14 ;PB!!
  1269. ;pop r13 ;PB!!
  1270. ret ; return
  1271. d16s_5: rol drem16sL ;shift dividend into remainder
  1272. rol drem16sH
  1273. sub drem16sL,dv16sL ;remainder = remainder - divisor
  1274. sbc drem16sH,dv16sH ;
  1275. brcc d16s_6 ;if result negative
  1276. add drem16sL,dv16sL ; restore remainder
  1277. adc drem16sH,dv16sH
  1278. clc ; clear carry to be shifted into result
  1279. rjmp d16s_3 ;else
  1280. d16s_6: sec ; set carry to be shifted into result
  1281. rjmp d16s_3
  1282.  
  1283. ;-----------------------------------------------
  1284.  
  1285. test_div16s:
  1286. ;***** Divide Two Signed 16-Bit Numbers (-22,222/10)
  1287. ldi dd16sL,low(-22222)
  1288. ldi dd16sH,high(-22222)
  1289. ldi dv16sL,low(10)
  1290. ldi dv16sH,high(10)
  1291. rcall div16s ;result: $f752 (-2222)
  1292. ;remainder: $0002 (2)
  1293.  
  1294. forever:rjmp forever
  1295. ;----------------------------------
  1296. test_slashMod:
  1297. ldi r16,$12
  1298. mypush r16
  1299. ldi r16,$34
  1300. mypush r16
  1301. ldi r16,$56 ;NB this is $3412 not $1234
  1302. mypush r16
  1303. ldi r16,$00
  1304. mypush r16
  1305. rcall slashMod ;$3412 / $56 = $9b rem 0 works
  1306. tslm: rjmp tslm
  1307.  
  1308. ;---------------------------------------
  1309. ;From http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#hex2bin
  1310. ; Hex4ToBin2
  1311. ; converts a 4-digit-hex-ascii to a 16-bit-binary
  1312. ; In: Z points to first digit of a Hex-ASCII-coded number
  1313. ; Out: T-flag has general result:
  1314. ; T=0: rBin1H:L has the 16-bit-binary result, Z points
  1315. ; to the first digit of the Hex-ASCII number
  1316. ; T=1: illegal character encountered, Z points to the
  1317. ; first non-hex-ASCII character
  1318. ; Used registers: rBin1H:L (result), R0 (restored after
  1319. ; use), rmp
  1320. ; Called subroutines: Hex2ToBin1, Hex1ToBin1
  1321.  
  1322. .def rBin1H =r17
  1323. .def rBin1L = r16
  1324. .def rmp = r18
  1325. ;
  1326. Hex4ToBin2:
  1327. clt ; Clear error flag
  1328. rcall Hex2ToBin1 ; convert two digits hex to Byte
  1329. brts Hex4ToBin2a ; Error, go back
  1330. mov rBin1H,rmp ; Byte to result MSB
  1331. rcall Hex2ToBin1 ; next two chars
  1332. brts Hex4ToBin2a ; Error, go back
  1333. mov rBin1L,rmp ; Byte to result LSB
  1334. sbiw ZL,4 ; result ok, go back to start
  1335. Hex4ToBin2a:
  1336. ret
  1337. ;
  1338. ; Hex2ToBin1 converts 2-digit-hex-ASCII to 8-bit-binary
  1339. ; Called By: Hex4ToBin2
  1340. ;
  1341. Hex2ToBin1:
  1342. push R0 ; Save register
  1343. rcall Hex1ToBin1 ; Read next char
  1344. brts Hex2ToBin1a ; Error
  1345. swap rmp; To upper nibble
  1346. mov R0,rmp ; interim storage
  1347. rcall Hex1ToBin1 ; Read another char
  1348. brts Hex2ToBin1a ; Error
  1349. or rmp,R0 ; pack the two nibbles together
  1350. Hex2ToBin1a:
  1351. pop R0 ; Restore R0
  1352. ret ; and return
  1353. ;
  1354. ; Hex1ToBin1 reads one char and converts to binary
  1355. ;
  1356. Hex1ToBin1:
  1357. ld rmp,z+ ; read the char
  1358. subi rmp,'0' ; ASCII to binary
  1359. brcs Hex1ToBin1b ; Error in char
  1360. cpi rmp,10 ; A..F
  1361. brcs Hex1ToBin1c ; not A..F
  1362. cpi rmp,$30 ; small letters?
  1363. brcs Hex1ToBin1a ; No
  1364. subi rmp,$20 ; small to capital letters
  1365. Hex1ToBin1a:
  1366. subi rmp,7 ; A..F
  1367. cpi rmp,10 ; A..F?
  1368. brcs Hex1ToBin1b ; Error, is smaller than A
  1369. cpi rmp,16 ; bigger than F?
  1370. brcs Hex1ToBin1c ; No, digit ok
  1371. Hex1ToBin1b: ; Error
  1372. sbiw ZL,1 ; one back
  1373. set ; Set flag
  1374. Hex1ToBin1c:
  1375. ret ; Return
  1376. ;--------------------------------------
  1377. test_Hex4ToBin2:
  1378. pushz
  1379. ldi zl,$60
  1380. clr zh ;z now points to start of buf1
  1381. ldi r16,'0'
  1382. st z+,r16
  1383. ldi r16,'f'
  1384. st z+,r16
  1385. ldi r16,'2'
  1386. st z+,r16
  1387. ldi r16,'3'
  1388. st z+,r16
  1389. ldi zl,$60
  1390. clr zh ;z now points back to start of buf1
  1391. rcall Hex4ToBin2
  1392. popz
  1393. th4: rjmp th4
  1394. ;-------------------------------------
  1395. numberh: ;word not in dictionary. Try to convert it to hex.
  1396. pushz ;algorithm uses z, pity
  1397. movw zl,r24 ;r4,25 = w holds start of current word
  1398. ;z now points eg to '12ab'start. If t=0 then it coverts to real hex
  1399. rcall hex4ToBin2 ;try to convert
  1400. ;above call needs 4 hex digits to emerge with t=0 and binary in r16,17
  1401. ;want this. If t=0 stack r16,17 and carry on interpreting, else emerge with
  1402. ; t=1 and zpointing to first problem char
  1403. brtc gotHex
  1404. ; if here there's a problem that z is pointing to. Bail out of interpret line
  1405. clr STOP
  1406. inc STOP
  1407. rjmp outnh
  1408.  
  1409. gotHex: ;sucess.Real hex in r16,17
  1410. mypush2 r16,r17 ; so push num onto mystack
  1411. ;maybe we're compiling. If so, push num into dic preceded by a call to stackme_2
  1412. tst STATE
  1413. breq outnh ;STATE =0 means executing
  1414. ; rcall tic
  1415. ; .db "stackme_2" ;has to be in dic before a number. cfa of stackme_2 on stack
  1416. rcall compstackme_2
  1417. ; rcall compileme ;insert "rcall stackme_2"opcode into dic
  1418. rcall comma ;there's the number going in
  1419.  
  1420. outnh:
  1421. popz ; but will it be pointing to "right"place in buf1? Yes now OK
  1422.  
  1423. ret
  1424. ; numberh not working fully, ie doesn't point to right place after action.
  1425. ; also no action if not a number? DONE better save this first.
  1426. ;---------------------------------
  1427. ;eeroutines
  1428. eewritebyte: ;write what's in r16 to eeprom adr in r18,19
  1429. sbic EECR,EEPE
  1430. rjmp eewritebyte ;keep looping til ready to write
  1431. ;if here the previous write is all done and we can write the next byte to eeprom
  1432. out EEARH,r19
  1433. out EEARL,r18 ;adr done
  1434. out EEDR,r16 ;byte in right place now
  1435. sbi EECR,EEMPE
  1436. sbi EECR,EEPE ;last 2 instruc write eprom. Takes 3.4 ms
  1437. ret
  1438. ;test with %!
  1439. ;---------------------------------
  1440. eereadbyte: ; read eeprom byte at adr in r18,19 into r16
  1441. ; Wait for completion of previous write
  1442. sbic EECR,EEPE
  1443. rjmp eereadbyte
  1444. ; Set up address (r18:r17) in address register
  1445. out EEARH, r19
  1446. out EEARL, r18
  1447. ; Start eeprom read by writing EERE
  1448. sbi EECR,EERE
  1449. ; Read data from data register
  1450. in r16,EEDR
  1451. ret
  1452. ;------------------------------
  1453. setupforflashin: ;using here etc get appropriate page, offset,myhere values.
  1454. ldi r16,low(HERE)
  1455. ldi r17,high(HERE) ;get here, but from eeprom better?
  1456. mypush2 r16,r17
  1457. rcall stackme_2
  1458. .dw 0002
  1459. rcall star ;now have current HERE in bytes in flash. But what is myhere?
  1460. rcall stackme_2
  1461. .db $0040 ;64 bytes per page
  1462. rcall slashMod
  1463. ;offset on top pagenum under. eg pg 0047, offset 0012
  1464. mypop2 r9,r8 ;store offset (in bytes)
  1465. rcall stackme_2
  1466. .db $0040
  1467. rcall star ;pgnum*64 = byte adr of start of flash page
  1468. mypop2 r7,r6
  1469. mypush2 r8,r9 ;push back offset
  1470. rcall stackme_2
  1471. .dw buf2
  1472. nop
  1473. ;at this stage we have offset in r8,r9 (0012). Also byte adr of flash page
  1474. ; start in r6,r7.(11c0) Stk is (offset buf2Start --) (0012 00E0 --). Need to
  1475. ; add these two together to get myhere, the pointer to RAM here position.
  1476. rcall plus ;add offset to buf2 start to get myhere (00f2)
  1477. ; put my here in r4,r5 for time being.
  1478. mypop2 r5,r4 ;contains eg 00f2 <--myhere
  1479. pushz ;going to use z so save it
  1480. movw zl,r6 ;r6,7 have byte adr of flsh pg strt
  1481. pushx ;save x
  1482. ldi xl,low(buf2)
  1483. ldi xh,high(buf2) ;point x to start of buf2
  1484. ldi r18,128 ;r18=ctr. Two flash pages = 128 bytes
  1485. upflash:
  1486. lpm r16,z+ ;get byte from flash page
  1487. st x+, r16 ; and put into buf2
  1488. dec r18
  1489. brne upflash
  1490. ;done. Now have two flash pages in ram in buf2. Myhere points to where next
  1491. ; entry will go. Where's page num?
  1492. popx
  1493. popz ;as if nothing happened
  1494.  
  1495.  
  1496. ret
  1497.  
  1498.  
  1499.  
  1500. ;outsufi: rjmp outsufi
  1501. ;-----------------------------------
  1502. burneepromvars: ;send latest versions of eHERE and eLATEST to eeprom
  1503. ldi r16,low(HERE)
  1504. ldi r17,high(HERE)
  1505. mypush2 r16,r17
  1506. ;up top we have .equ eHERE = $0010
  1507. ldi r16,low(eHERE)
  1508. ldi r17,high(eHERE)
  1509. mypush2 r16,r17
  1510. ;now have n16 eadr on stack ready for e!
  1511. rcall percentstore
  1512.  
  1513. ;send latest versions of eLATEST to eeprom
  1514. ldi r16,low(LATEST)
  1515. ldi r17,high(LATEST)
  1516. mypush2 r16,r17
  1517. ;up top we have .equ eLATEST = $0010
  1518. ldi r16,low(eLATEST)
  1519. ldi r17,high(eLATEST)
  1520. mypush2 r16,r17
  1521. ;now have n16 eadr on stack ready for e!
  1522. rcall percentstore
  1523. ret
  1524. ;-------------------------------------------
  1525. coloncode: ;this is the classic colon defining word.
  1526. rcall setupforflashin ;get all the relevant vars and bring in flash to buf2
  1527. rcall relinkcode ; insert link into first cell
  1528. rcall create ;compile word preceeded by length
  1529. rcall leftbrac ;set state to 1, we're compiling
  1530. ret ;now every word gets compiled until we hit ";"
  1531. ;-------------------------
  1532. relinkcode: ;put LATEST into where myhere is pointing and update ptr = myhere
  1533. ;also create mylatest
  1534. rcall getlatest ;now on stack
  1535. mypopa ;latest in r16,17
  1536. pushz ;better save z
  1537. movw mylatest,myhere ;mylatest <-- myhere
  1538. movw zl,myhere ;z now points to next available spot in buf2
  1539. st z+,r17 ;problem. Don't work unless highbye first in mem.Why?
  1540. st z+,r16 ;now have new link in start of dic word
  1541. movw myhere,zl ;update myhere to point to length byte. (Not yet there.)
  1542. popz ;restore z
  1543. ret
  1544. ;-------------------------------------------------
  1545. create: ;put word after ":" into dictionary, aftyer link, preceeded by len
  1546. rcall word ;start with x pnting just after ":".End with len in r20, x pointing to
  1547. ; space just after word and start of word in w=r24,25
  1548. pushz ;save z. It's going to be used on ram dictionary
  1549. movw zl,myhere ;z now pnts to next spot in ram dic
  1550. st z+,r20 ; put len byte into ram dic
  1551. mov r18,r20 ;use r18 as ctr, don't wreck r20
  1552. pushx ;save x. It's going to be word ptr in buf1
  1553. movw xl,wl ;x now points to start of word. Going to be sent to buf2
  1554. sendbytes:
  1555. ld r16,x+ ;tx byte from buf1 to
  1556. st z+,r16 ; buf2
  1557. dec r18 ;repeat r20=r18=len times
  1558. brne sendbytes
  1559.  
  1560. sbrs r30,0 ;skip next instruction if final bit lsb = 1
  1561. rjmp downcr
  1562. ;if here lsb = 1 so we're on a padding byte and have to add 1 to get to a 2 byte boundary
  1563. clr r16
  1564. st z+,r16 ;insert padding byte
  1565. ;inc r30
  1566. ;brcc downcr
  1567. ;inc r31 ;add one to z before converting to bytes
  1568.  
  1569. downcr:
  1570. movw myhere,zl ;myhere now points to beyond word in dic
  1571. popx
  1572. popz
  1573. ret ;with word in dic
  1574. ;----------------------------------------------
  1575. leftbrac: ;classic turn on compiling
  1576. clr STATE
  1577. inc STATE ;state =1 ==> now compiling
  1578. ret
  1579. ;------------------------
  1580. compilecode: ;come here with STATE =1 ie compile, not execute. Want to put
  1581. ; eg rcall dup in code in dictionary but not to execute dup. If here
  1582. ; z points to byte address of word
  1583. mypush2 zl,zh
  1584. compileme:
  1585. mypush2 myhere,r5 ;push ptr to RAM dic
  1586. ;next is entry point for eg ' stackme2 already on stack and have to compile
  1587.  
  1588. ldi r16,low(buf2)
  1589. ldi r17,high(buf2) ;start of buf that conatins flash pg in RAM
  1590. mypush2 r16,r17
  1591. rcall minus ; myhere - buf2-start = offset in page
  1592. mypush2 SOFPG,r7 ;push start of flash page address
  1593. rcall plus ;SOFPG + offset = adr of next rcall in dic
  1594. ;if here we have two flash addresses on the stack. TOS = here. Next is there.
  1595. ;want to insert code for "rcall there w"hen I'm at here. eg current debugging indicates
  1596. ; here = $11EB and there is $1012 (cfa of "two"). First compute
  1597. ; relative branch "there - here -2". Then fiddle this val into the rcall opcode
  1598. rcall minus ;that;s there - here. Usu negative.
  1599. ;I got fffffffff..ffe27 for above vals. First mask off all those f's
  1600. rcall two ;stack a 2
  1601. rcall minus ;now have there-here -2 = fe24. When there,here in bytes.
  1602. mypopa ;bring fe26 into r16,17
  1603. clc
  1604. ror r17
  1605. ror r16 ;now a:= a/2
  1606. ldi r18,$ff
  1607. ldi r19,$0f ;mask
  1608. and r16,r18
  1609. and r17,r19
  1610. ; mypush2 r16,r17 ;now fe26 --> 0e26
  1611. ;the rcall opcode is Dxxx where xxx is the branch
  1612. ; mypopa ;bring fe26 into r16,17
  1613. ldi r19, $d0 ;mask
  1614. or r17,r19
  1615. mypush2 r16,r17 ;now have $de26 on stack which is (?) rcall two
  1616. rcall comma ;store this opcode into dic. myhere is ptr
  1617. ret
  1618. ;---------------------------
  1619. stackme_2: ;stacks on my stack next 16bit num. Address of 16bit number is on SP-stack
  1620. ; Used like this stackme_2 0034. Puts 0034 on myStack and increments past number on return stack.
  1621. pop r17
  1622. pop r16 ; they now contain eg 0x0804 which contain the 16bit num
  1623. movw zl,r16 ;z now points to cell that cobtains the number
  1624. clc
  1625. rol zl
  1626. rol zh ;double word address for z. lpm coming up
  1627.  
  1628.  
  1629.  
  1630. lpm r16,z+
  1631. lpm r17,z+ ;now have 16bit number in r16,17
  1632.  
  1633. st y+,r16
  1634. st y+, r17 ;mystack now contains the number
  1635.  
  1636. clc
  1637. ror zh
  1638. ror zl ;halve the z pointer to step past the number to return at the right place
  1639.  
  1640. push zl
  1641. push zh
  1642.  
  1643. ret
  1644. ;------------------------------flash write section--------------------
  1645.  
  1646. do_spm:
  1647. ;lds r16,SPMCSR
  1648. in r16,SPMCSR
  1649. andi r16,1
  1650. cpi r16,1
  1651. breq do_spm
  1652. mov r16,spmcsr_val
  1653. out SPMCSR,r16
  1654. spm
  1655. ret
  1656. ;-------------------------------------------------------------------
  1657. buf2ToFlashBuffer: ;send the 64 bytes, 32 words to flash page <-- Z pnts there.
  1658. push r30 ;save for later spm work.
  1659. push r19
  1660. push xl
  1661. push xh ;used as buf_ctr but may interfere with other uses
  1662. ldi XL,low(buf2) ;X pnts to buf1 that contains the 64 bytes.
  1663. ldi XH, high(buf2)
  1664. ;assume Z is already pointing to correct flash start of page.
  1665. flashbuf:
  1666. ldi buf_ctr,32 ;send 32 words
  1667. sendr0r1:
  1668. ld r16, x+ ;get first byte
  1669. mov r0,r16 ; into r0
  1670. ld r16, x+ ; and get the second of the pair into
  1671. mov r1,r16 ; into r1
  1672. ldi spmcsr_val,01 ;set up for write into spare buffer flash page
  1673. rcall do_spm ;that's r0,r1 gone in.
  1674. inc r30
  1675. inc r30
  1676. dec buf_ctr ;done 32 times?
  1677. brne sendr0r1
  1678. pop xh
  1679. pop xl
  1680. pop r19 ;dont need buf_ctr any more.
  1681. pop r30 ;for next spm job
  1682.  
  1683. ret
  1684. ;--------------------------------------------------------------------------
  1685. ;TODO just have 1 burn routine with buf different
  1686. buf3ToFlashBuffer: ;send the 64 bytes, 32 words to flash page <-- Z pnts there.
  1687. push r30 ;save for later spm work.
  1688. push r19 ;used as buf_ctr but may interfere with other uses
  1689. push xl
  1690. push xh
  1691. ldi XL,low(buf2+64) ;X pnts to buf1 that contains the 64 bytes.
  1692. ldi XH, high(buf2+64)
  1693. ;assume Z is already pointing to correct flash start of page.
  1694. rjmp flashbuf
  1695. ldi buf_ctr,32 ;send 32 words
  1696. sendr0r3:
  1697. ld r16, x+ ;get first byte
  1698. mov r0,r16 ; into r0
  1699. ld r16, x+ ; and get the second of the pair into
  1700. mov r1,r16 ; into r1
  1701. ldi spmcsr_val,01 ;set up for write into spare buffer flash page
  1702. rcall do_spm ;that's r0,r1 gone in.
  1703. inc r30
  1704. inc r30
  1705. dec buf_ctr ;done 32 times?
  1706. brne sendr0r3
  1707. pop r19 ;dont need buf_ctr any more.
  1708. pop r30 ;for next spm job
  1709. ret
  1710.  
  1711. erasePage: ; assume Z points to start of a flash page. Erase it.
  1712. ldi spmcsr_val,0x03 ;this is the page erase command
  1713. rcall do_spm
  1714. ret
  1715. ;------------------------------------------------------------------
  1716. writePage:
  1717. ldi spmcsr_val, 0x05 ;command that writes temp buffer to flash. 64 bytes
  1718. rcall do_spm
  1719. nop ; page now written. z still points to start of this page
  1720. ret
  1721. ;---------------------------------------------------------------
  1722. test_buf2ToFlashBuffer: ;(adr_flashbufstartinBytes -- )
  1723. ; rcall fillBuf
  1724. ; ldi ZH, $10
  1725. ; ldi ZL,$c0 ;z=$01c0. Start of page 67.
  1726. rcall gethere
  1727. rcall double ;want bytes not words for flash adr
  1728. mypopa ;flashPgStart byte adr now in r16,17
  1729.  
  1730.  
  1731. movw zl,r16 ;z <--start of flash buffer
  1732. rcall erasePage
  1733. rcall buf2ToFlashBuffer
  1734. rcall writePage
  1735. herettt:
  1736. rjmp herettt
  1737. ;----------------------
  1738. ; burnbuf2. Come here from ";". The pair r6,r7 point to start of flash pg (bytes)
  1739. burnbuf2and3:
  1740. movw zl,r6 ;z now pnts to start of flash buf
  1741. rcall erasePage
  1742. rcall buf2ToFlashBuffer
  1743. rcall writePage
  1744. ;now going to burn next ram buffer to next flash page. Bump Z by 64 bytes.
  1745. adiw zh:zl,63 ;z now points to start of next flash buffer
  1746. lpm r16,z+ ;advance z pointer by one.adiw only lets max of 63 to be added.
  1747. ;now z points to start of next 64 byte buffer. Time to put buf3 into it.
  1748. rcall erasePage
  1749. rcall buf3ToFlashBuffer
  1750. rcall writePage
  1751. ret
  1752. heret:
  1753. rjmp heret
  1754. ;-------------------------------------------------------------
  1755. updatevars: ;after doing a colon def we have to update sys vars
  1756. ;TODO new version of LATEST is just old version of HERE.
  1757. ;TODO rplace all this code with updatevars2
  1758. ; just shif HERE into LATEST in eeprom to update. Gen. tidy required.
  1759. mypush2 r4,r5 ;put myhere on stack (E8)
  1760. ldi r16,low(buf2)
  1761. ldi r17,high(buf2)
  1762. mypush2 r16,r17 ;start of buf2 on stack (E0)
  1763. rcall minus ;myhere-buf2 = offset. (e8-e0 = 08)
  1764. mypush2 SOFPG,r7 ; push onto stk start adr of flash page
  1765. rcall plus ;SOFG + offset = new HERE
  1766. ;now put also on stack new version of LATEST
  1767. mypush2 r2,r3 ;that's mylatest on stack
  1768. ldi r16,low(buf2)
  1769. ldi r17,high(buf2)
  1770. mypush2 r16,r17 ;start of buf2 on stack (E0)
  1771. rcall minus ;myhere-buf2 = offset. (e8-e0 = 08)
  1772. mypush2 SOFPG,r7 ; push onto stk start adr of flash page
  1773. rcall plus ;SOFG + offset = new LATEST
  1774. ; now have both LATEST (tos) and HERE on stack. Burn these into eeprom
  1775. ;up top we have .equ eLATEST = $0010
  1776. ;But it's too big. In bytes and causing probs. Solution=covert to words
  1777. rcall halve
  1778. ldi r16,low(eLATEST)
  1779. ldi r17,high(eLATEST)
  1780. mypush2 r16,r17
  1781. ;now have n16 eadr on stack ready for e!
  1782. rcall percentstore
  1783. ; TODO the value for HERE is prob in bytes too. Convert to words.
  1784. ;up top we have .equ eLATEST = $0010
  1785. ldi r16,low(eHERE)
  1786. ldi r17,high(eHERE)
  1787. mypush2 r16,r17
  1788. ;now have n16 eadr on stack ready for e!
  1789. rcall halve ;TODO check this
  1790. rcall percentstore
  1791. ret ;with stack clear and new vals for HERE and LATEST in eeprom
  1792. ;----------
  1793. ;;;;;;;;;;;;;;;;;;;;;;;;;;;Now serial stuff starts;;;;;;;;;;;;;;;;;;;;;;;;;
  1794. halfBitTime: ;better name for this delay. Half of 1/600
  1795. ;myDelay1200:
  1796. ;ldi r21,13 ; 13 works for m328 at 16Mhz
  1797. push r20
  1798. push r21
  1799. ldi r21,7 ;try 7 for tiny85 at 8Hmz
  1800. ldi r20,130 ;r20,21 at 130,7 give 833uS. Good for 600baud at 8Mhz
  1801. starthbt:
  1802. inc r20
  1803. nop
  1804. brne starthbt
  1805. dec r21
  1806. brne starthbt
  1807. pop r21
  1808. pop r20
  1809. ret
  1810. ;--------------------------------------------------
  1811. oneBitTime:
  1812. rcall halfBitTime
  1813. rcall halfBitTime
  1814. ret
  1815. ;-------------------------------------------------
  1816. sendAZero:
  1817. ;output 0 on Tx pin
  1818. cbi PORTB,TX_PIN ; send a zero out PB0
  1819. ret
  1820. ;-----------------------------------------------------
  1821.  
  1822. sendAOne:
  1823. ;output 1 on Tx pin
  1824. sbi PORTB,TX_PIN ; send a zero out PB0
  1825. ret
  1826. ;-----------------------------------------------------
  1827. sendStartBit:
  1828. ; send a 0 for one bit time
  1829. rcall sendAZero
  1830. rcall oneBitTime
  1831. ret
  1832. ;-------------------------------------------------------
  1833. sendNextDataBit: ;main output routine for serial tx
  1834. lsr serialByteReg ;push high bit into carry flag then inspect it
  1835. ;originally did lsl but found lsb first.
  1836. brcc gotzero ;if it's a 0 do nothing
  1837. rcall sendAOne ;must have been a 1 in carry
  1838. rjmp down
  1839. gotzero:
  1840. rcall sendAZero ;if here carry was a zero
  1841. down:
  1842. rcall oneBitTime ;so that 1 or 0 lasts 1/600 sec
  1843. ret
  1844. ;-------------------------------------------------------------
  1845. send8DataBits: ; send all bits in serialByteReg
  1846. ldi counterReg,8 ;8 data bits
  1847. sendBit:
  1848. rcall sendNextDataBit
  1849. dec counterReg
  1850. brne sendBit
  1851. ret
  1852. ;--------------------------------------------------------
  1853. sendStopBit:
  1854. ; send a 1 for one bit time
  1855. rcall sendAOne
  1856. rcall oneBitTime
  1857. ret
  1858. ;--------------------------------------------------------
  1859. sendSerialByte: ;main routine. Byte in serialByteReg = r16
  1860. push counterReg
  1861. rcall sendStartBit
  1862. rcall send8DataBits
  1863. rcall sendStopBit
  1864. rcall sendStopBit ;two stops
  1865. pop counterReg
  1866. ret
  1867. ;**************************************************************
  1868. serialTest0: ;output series of 'AAAA..'s
  1869. ldi serialByteReg, 0x43 ;0x41
  1870. rcall sendSerialByte
  1871. rcall oneBitTime ; take a rest
  1872. ldi r16,$44
  1873. mypush r16
  1874. rcall emitcode
  1875.  
  1876. rjmp serialTest0 ;continue forever
  1877. ;---------------------------------------------------------
  1878. ;---------Now do SerialRx routines-------------------
  1879. waitForHigh: ;loop til RX is high
  1880. sbis PINB,RX_PIN ;test that pin for set (PB2)
  1881. rjmp waitForHigh ; loop if rx pin is low
  1882. ret
  1883. ;-----------------------------------------------
  1884. waitForLow: ;PRONBLEMs loop til RX is low. FIXED.
  1885. sbic PINB,2 ;test that pin for set (PB2)
  1886. rjmp waitForLow ; loop if rx pin is high
  1887. ret
  1888. ;---------------------------------------------------
  1889. waitForStartBit: ;loop til get a real start bit
  1890. rcall waitForHigh ;should be marking at start
  1891. rcall waitForLow ;gone low. might be noise
  1892. rcall halfBitTime ;is it still low in middle of bit time
  1893. sbic PINB,RX_PIN ;..well, is it?
  1894. rjmp waitForStartBit ;loop if level gone back high. Not a start bit.
  1895. ret ;we've got our start bit
  1896. ;----------------------------------------------------
  1897. checkForStopBit: ;at end, get carry flag to reflect level. Prob if c=0
  1898. rcall oneBitTime ; go into stop bit frame, halfway
  1899. sec ;should stay a 1 in C if stop bit OK
  1900. sbis PINB,RX_PIN ;don't clc if bit is high
  1901. clc ;but only if we have a weird low stop bit
  1902. ret ;with carry flag = stop bit. Should be a 1
  1903. ;-------------------------------------------------------------
  1904. get8Bits: ;get the 8 data bits. No frame stuff
  1905. clr rxbyte ;this will fill up with bits read from RX_PIN
  1906. push counterReg ;going to use this so save contents for later
  1907. ldi counterReg,8 ;because we're expecting 8 databits
  1908. nextBit:
  1909. rcall oneBitTime ;first enter here when mid-startbit
  1910. rcall rxABit ;get one bit
  1911. dec counterReg ;done?
  1912. brne nextBit ;no, round again
  1913. pop counterReg ;yes, finished, restor counter and get out
  1914. ret
  1915. ;---------------------------------------------------------------
  1916. rxABit: ;big serial input routine for one bit
  1917. clc ;assume a 0
  1918. sbic PINB,RX_PIN ; skip nxt if pin low
  1919. sec ;rx pin was high
  1920. ror rxbyte ;carry flag rolls into msb first
  1921. ret
  1922. ;********************************
  1923. getSerialByte: ;big routine. Serial ends up in rxByte
  1924. push counterReg
  1925. rcall waitForStartBit ;**change
  1926. rcall get8Bits
  1927. rcall checkForStopBit
  1928. pop counterReg
  1929. ret ;with rxByte containing serial bye
  1930. ;----------------------------------------------------
  1931. serialTest1: ;output A then reflect input. Worked OK
  1932. ldi serialByteReg, 0x36 ;0x41
  1933. rcall sendSerialByte
  1934. rcall oneBitTime ; take a rest
  1935. rcall getSerialByte
  1936. mov serialByteReg,rxByte ;output what's been read
  1937. rcall sendSerialByte
  1938. rjmp serialTest1
  1939. ;--------------------------------------------------------
  1940. ;----------Now doing buffer work. Want to and from 64 bytes----------
  1941. fillBuf:
  1942. ldi ZL,low(buf1) ;buf1 is my buffer
  1943. ldi ZH, high(buf1) ;Z now points to buf1
  1944. ldi counterReg,64 ;64 bytes in buffer
  1945. ldi r16,$30
  1946. storeB0:
  1947. st z+,r16
  1948. inc r16
  1949. dec counterReg
  1950. brne storeB0
  1951. herefb:
  1952. ; rjmp herefb
  1953. ret
  1954. ;----------------------------------------------------------
  1955. serialStrOut: ;X points to start of string,r17 has length
  1956. ld serialByteReg, x+
  1957.  
  1958. rcall sendSerialByte
  1959. dec r17 ;got to end of string?
  1960. brne serialStrOut
  1961. ret
  1962. ;----------------------------------
  1963. test_serialStrOut:
  1964. rcall fillBuf
  1965. ldi XL,low(buf1) ;buf1 start of str
  1966. ldi XH, high(buf1)
  1967. ldi r17,64 ;going to send len=r17 bytes
  1968. rcall serialStrOut
  1969. here2:
  1970. rjmp here2
  1971. ;--------------------------------------
  1972. waitForCharD: ;wait til eg a 'D' is pressed then do something.
  1973. ldi serialByteReg, '>' ;0x41
  1974. rcall sendSerialByte
  1975. rcall oneBitTime ; take a rest
  1976. rcall getSerialByte
  1977. mov serialByteReg,rxByte ;output what's been read
  1978. cpi rxByte, 'D'
  1979. brne waitForCharD
  1980. ldi serialByteReg, '*'
  1981. rcall sendSerialByte
  1982. rjmp waitForCharD
  1983. ;-----------------------------------------------------------
  1984. dumpbuf1:
  1985. ldi XL,low(buf1) ;buf1 start of str
  1986. ldi XH, high(buf1)
  1987. ldi r17,64 ;going to send len=r17 bytes
  1988. rcall serialStrOut
  1989. ret
  1990. ;-------------------------------------------------------------
  1991. test_dumpbuf1:
  1992. rcall fillBuf
  1993. rcall getSerialByte ;any one will do.
  1994. rcall dumpbuf1
  1995. rjmp test_dumpbuf1
  1996. ;----------------------------------------------------------
  1997. waitForDDump: ;wait til eg a 'D' is pressed then dump buf1
  1998. ldi serialByteReg, '>' ;0x41
  1999. rcall sendSerialByte
  2000. rcall oneBitTime ; take a rest
  2001. rcall getSerialByte
  2002. mov serialByteReg,rxByte ;output what's been read
  2003. cpi rxByte, 'D'
  2004. brne waitForDDump
  2005. rcall dumpbuf1
  2006. rjmp waitForCharD
  2007. ;---------------------------------------------------------------
  2008. rxStrEndCR: ;get a serial string that ends with CR
  2009. clr counterReg
  2010. ldi XL,low(buf1) ;buf1 is where str will go
  2011. ldi XH, high(buf1)
  2012. upsec:
  2013. rcall getSerialByte
  2014.  
  2015. st x+, rxByte ;char goes into buffer="buf1"
  2016.  
  2017. cpi rxByte,$0d ;is it CR = end of string?
  2018. breq fin
  2019. inc counterReg ;don't go over 64 bytes
  2020. cpi counterReg,64
  2021. brne upsec ;not too long and not CR so keep going
  2022. fin:
  2023. ret
  2024. ;---------------------------------------------
  2025. test_rxStrEndCR: ;just a test of above
  2026. rcall OK
  2027. rcall CR
  2028. rcall rxStrEndCR
  2029. rcall dumpbuf1
  2030. rcall CR
  2031. ; rcall waitForDDump
  2032. rjmp test_rxStrEndCR
  2033. ;------------------------------------------------------
  2034. test2_rxStrEndCR: ;want a diagnostic dump if testing. Works with .IFDEF
  2035. rcall rxStrEndCR
  2036. .IFDEF testing
  2037. rcall dumpbuf1
  2038. .ENDIF
  2039. rjmp test2_rxStrEndCR
  2040. ;------------------------------------------------------------
  2041. rxStrWithLen: ;expect len char char char.. for len chars
  2042. push counterReg
  2043. ldi XL,low(buf1) ;buf1 is where str will go
  2044. ldi XH, high(buf1)
  2045. rcall getSerialByte ; get length bye Must be less than 65
  2046. mov counterReg, rxByte ;save len in counter
  2047. cpi counterReg,65 ;
  2048. brlo allOK ;less than 65 so carry on. Branch if Lower
  2049. ldi counterReg,64 ; if len>64 then len=64. Buffer = buf1 only 64 bytes
  2050. allOK:
  2051. tst counterReg ;zero yet?
  2052. breq finrs
  2053. rcall getSerialByte ;next serial input byte
  2054. st x+, rxByte ;put into buffer
  2055. dec counterReg ;have we done len=counterReg bytes?
  2056. rjmp allOK
  2057. finrs:
  2058. pop counterReg
  2059. ret
  2060. ;---------------------------------------------------------------
  2061. test_rsStrWithLen: ;works ok with macro $05GHIJKLM. Sends GHIJK
  2062. ldi r16, '#'
  2063. rcall sendSerialByte
  2064. rcall rxStrWithLen
  2065. rcall dumpbuf1
  2066. rjmp test_rsStrWithLen
  2067. ;-----------------------------now start forth i/o words like emit------------------
  2068. emitcode: ; (n8 --)classic emit
  2069. mypop r16
  2070. rcall sendserialbyte
  2071. ret
  2072. ;------------------------------------------------
  2073. insertret: ;semi has to end new word with ret = $9508 opcode
  2074. pushx ;both xl,xh saved for later
  2075. movw xl,myhere ;myhere points to next available spot in ram dic
  2076. ldi r16,$08
  2077. st x+,r16 ;$08 part goes first
  2078. ldi r16,$95
  2079. st x+,r16 ;ret now in ram. Just tidy pointers
  2080. movw myhere,xl
  2081. popx ;so x back where it was and ret inserted.
  2082. ret
  2083. ;--------------------------------
  2084. equalcode: ;(n1 n2 -- flag) if n1 = n2 flag = 0001 else 0000
  2085. mypopa
  2086. mypopb ; now have TOS in r16,17, underneath that in r18,19
  2087. cp r16,r18 ;low bytes =?
  2088. brne zout ;not equal so go out
  2089. cp r17,r19 ;hi bytes =?
  2090. brne zout ;no, so out
  2091. ;if here both n16's are equal so push a 0001
  2092. rcall one
  2093. rjmp aout ;done
  2094. zout:
  2095. rcall zero ;not = so push a zero
  2096. aout:
  2097. ret ;with a flag on stack replacing to n16's
  2098. ;------------------------------
  2099. ;TODO eliminate below and replace with simpler RAM jmp code.
  2100. calcjumpcode: ;(to from -- opcode_for_rjmp to at from)
  2101. ;used when compiling. What is the rjmp opcode if
  2102. ; we know the from and to adr on stack. ( to fr --)
  2103. ldi r16, low(buf2)
  2104. ldi r17, high(buf2)
  2105. mypush2 r16,r17 ; (to fr $e0 --)
  2106. rcall dup ;t f $e0 $eo
  2107. rcall unrot ;t $e0 fr $e0
  2108. rcall minus ;t $e0 frOffset
  2109. rcall unrot ;frOffset t $e0
  2110. rcall minus ;frOffset toOffset
  2111. ;now apply these offsets in flash buffer. Add them to start of flash buffer adr
  2112. mypush2 SOFPG,r7 ; frOffset toOffset SOFPG
  2113. rcall dup ;frOffset toOffset SOFPG SOFPG
  2114. rcall unrot ;frOffset SOFPG toOffset SOFPG
  2115. rcall plus ;frOffset SOFPG toFlashAdr
  2116. rcall unrot ;toFlashAdr frOffset SOFPG
  2117. rcall plus ;toFlashAdr frFlashAdr
  2118. rcall minus ;to -from give last 3 nibbles in rjmp opcode +1
  2119. rcall one
  2120. rcall minus ; now have to - from -1
  2121. rcall stackme_2
  2122. .dw $0fff
  2123. rcall andd ; now have eg. 0f20. Want Cf20
  2124. rcall stackme_2
  2125. .dw $c000 ;should now have right opcode eg cf20
  2126. ret ;with correct rjmp kkk on stack. Ready to insert into RAM dic.
  2127. ;-------------------
  2128. stackmyhere: ;( --- adr) put RAM ptr myhere on stack
  2129. mypush2 myhere, r5
  2130. ret
  2131. ;---------------------------
  2132. begincode: ;when using BEGIN just stack current address.No dic entry
  2133. rcall stackmyhere ;put next adr on stack
  2134. ret
  2135. ;----------------------------
  2136. stkmyhere: ;put myhere on the stack, handy
  2137. mypush2 myhere,r5
  2138. ret
  2139. ;-----------------------------------
  2140. stkSOBuf2: ;stack start of buf2. Handy.
  2141. ldi r16,low(buf2)
  2142. ldi r17,high(buf2)
  2143. mypush2 r16,r17
  2144. ret ;with adr of buf2 on stk
  2145. ;--------------------------
  2146. stkSOFPG: ;put start of flash page on stack, In bytes.
  2147. mypush2 SOFPG,r7
  2148. ret ;with start of current flash page's adr on stack.
  2149. ;-------------------------------
  2150. stklatestadr: ;put e-adr of eLatest. Currently 012 in eeprom
  2151. ldi r16,low(eLATEST)
  2152. ldi r17,high(eLATEST)
  2153. mypush2 r16,r17
  2154. ret ;with 012 or adr of eLatest on stk
  2155. ;-------------------------------------
  2156. stkhereadr: ;same as above but for HERE
  2157. ldi r16,low(eHERE)
  2158. ldi r17,high(eHERE)
  2159. mypush2 r16,r17
  2160. ret ;with adr of ehere,current eeprom adr = $010
  2161. ;-------------------------------------------
  2162. updatevars2: ;better version of update vars. Come here after ";"
  2163. ;TODO check this version.DONE and eliminate other one.
  2164. rcall gethere ;the HERE val now on stack. It's a pointer to flash.
  2165. rcall stklatestadr ;usually 012
  2166. rcall percentstore
  2167. ;now with LATEST now containing old HERE. Next fix HERE
  2168. rcall stkmyhere ;current ptr to RAM dic's next free byte
  2169. rcall stkSOBuf2 ;start of buf2 adr
  2170. rcall minus ;gives distance into the buffer
  2171. rcall stkSOFPG ;will add distance to start of flashbuf
  2172. rcall plus ;got flash adr, but in bytes
  2173. rcall halve ;now adr in words
  2174. rcall stkhereadr ;usually %010 in eeprom
  2175. rcall percentstore ;eHERE now updated
  2176. ret ;with vals for HERE and LATEST in eeprom updated after ";"
  2177. ;--------------------
  2178. testOKCR:
  2179. rcall OK
  2180. rcall OK
  2181. rcall CR
  2182. rjmp testOKCR
  2183. ;--------------------
  2184. serialFill: ;main input routine from terminal. Output OK} then
  2185. ; wait until buf1 has string of words ( <64 chars?) ending in $0d
  2186. rcall CR
  2187. rcall OK
  2188. rcall rxStrEndCR
  2189. ret ; buf1 now filled with words from terminal
  2190.  
  2191. ;------------------------dump routines _______________
  2192. outnib: ;given $23 in r16, output the 3 as '3' = $33
  2193. push r18 ;going to use this
  2194. andi r16,$0f ; $3a --> $0a
  2195. cpi r16,$0a ;more than 10?
  2196. brge gothexo ;Nibble >= 10 jump down to gothex
  2197. ldi r18,$30 ; add $30 to 0..9
  2198. rjmp doneon
  2199. gothexo:
  2200. ldi r18,$37
  2201. doneon:
  2202. add r16,r18 ;now r16 nibble $03 is a '3'
  2203. rcall sendserialbyte ;print it
  2204. pop r18 ;used this as counter
  2205. ret ;note, it wrecks r16
  2206. ;--------------------------------------------
  2207. d16: ;dump contents of r16. Good for debugging.
  2208. push r16 ;keep contents for later
  2209. push r16 ;need this one after swap
  2210. swap r16 ;$34 wants 3 to come out first
  2211. rcall outnib ;print ascii eg '3'in above if r16 = $34
  2212. pop r16 ;get nice version back eg $34
  2213. rcall outnib ;print the '4'
  2214. pop r16 ;so r16 not wrecked.
  2215. ret ;with r16 printed in ascii
  2216. ;-----------------------------------
  2217. test_d16: ldi r16,$a5
  2218. rcall d16
  2219. ldi r16,$b6
  2220. rcall d16
  2221. rjmp test_d16
  2222. ;--------------------------------
  2223. d1617: ;dump r16 and r17 for debugging purposes
  2224. push r16
  2225. push r17 ;
  2226. push r16 ;just one min
  2227. mov r16, r17
  2228. rcall d16 ;that's r17 gone
  2229. pop r16
  2230. rcall d16 ;and then r16
  2231. pop r17
  2232. pop r16
  2233. ret ;with r17:r16 output in ascii
  2234. ;----------------------------------------
  2235. test_d1617:
  2236. ldi r16,$34
  2237. ldi r17,$1F
  2238. rcall d1617
  2239. rjmp test_d1617
  2240. ;-----------------------------------
  2241. dlowR: ;dump low registers. r0..r15 for debugging
  2242. push r16
  2243. push r18
  2244. pushx ;macro
  2245. clr xl
  2246. clr xh
  2247. ldi r18,16 ;r18 is a counter
  2248. prlow:
  2249. ld r16,x+ ;assume is x is 0 we'll get r0
  2250. rcall d16
  2251. rcall spacecode
  2252. dec r18
  2253. cpi r18,$07
  2254. breq doeseq7
  2255. tst r18
  2256. brne prlow
  2257. rjmp outprl
  2258. doeseq7:
  2259. ldi r16,'L'
  2260. rcall sendserialbyte
  2261. rcall spacecode
  2262. rjmp prlow
  2263.  
  2264. outprl:
  2265. popx ;macro
  2266. pop r18
  2267. pop r16
  2268. ret ;with all the registers r0 ..r15 output in ascii to terminal screen
  2269. ;----------------------------------
  2270. test_dlowR:
  2271. rcall CR
  2272. ldi r16,$02
  2273. mov r0,r16
  2274. ldi r16,$52
  2275. mov r5,r16
  2276. ldi r16,$f2
  2277. mov r15,r16
  2278. rcall dlowR
  2279. rcall CR
  2280. rjmp test_dlowR
  2281. ;-----------------------------
  2282. spacecode: ;output a space
  2283. push r16
  2284. ldi r16,$20
  2285. rcall sendserialbyte
  2286. pop r16
  2287. ret
  2288. ;-------------------------------
  2289. dhighR: ;dump high registers. r18..r25 for debugging
  2290. push r16
  2291. push r17
  2292. pushx ;macro
  2293. ldi xl,18
  2294. ; clr xl
  2295. clr xh
  2296. ldi r17,8 ;r18 is a counter
  2297. prhi:
  2298. ld r16,x+ ;assume is x is 18 we'll get r18
  2299. rcall d16
  2300. rcall spacecode
  2301. dec r17
  2302. cpi r17,5
  2303. breq doeseq21
  2304. tst r17
  2305. brne prhi
  2306. rjmp outprh
  2307. doeseq21:
  2308. ldi r16,'H'
  2309. rcall sendserialbyte
  2310. rcall spacecode
  2311. rjmp prhi
  2312.  
  2313. outprh:
  2314. popx ;macro
  2315. pop r17
  2316. pop r16
  2317. ret ;with all the registers r0 ..r15 output in ascii to terminal screen
  2318. ;----------------------------------
  2319. test_dhighR:
  2320. rcall CR
  2321. ldi r18,$88
  2322. ldi r19,$19
  2323. ldi r20,$88 ;
  2324. ldi r21,$88
  2325. ldi r22,$22
  2326. ldi r23,$23
  2327. ldi r24,$24
  2328. ldi r25,$25
  2329. rcall dhighR
  2330. rcall CR
  2331. rjmp test_dhighR
  2332. ;------------------------------------
  2333. dxyz: ;dump the three pointer regs x,y,z
  2334.  
  2335. push r16
  2336. push r17
  2337. movw r16,xl ;r17:16 gets xh:xl
  2338. rcall d1617
  2339. rcall spacecode
  2340. movw r16,yl
  2341. rcall d1617
  2342. rcall spacecode
  2343. movw r16,zl
  2344. rcall d1617
  2345. rcall spacecode
  2346. pop r17
  2347. pop r16
  2348. ret ;with x,y,z output in ascii as a tripple
  2349. ;--------------------------------------
  2350. test_dxyz:
  2351. rcall CR
  2352. ldi xl,$12
  2353. ldi xh,$34
  2354. ldi yl,$56
  2355. ldi yh,$78
  2356. ldi zl,$9A
  2357. ldi zh,$bc
  2358. rcall CR
  2359. rcall dxyz
  2360. rcall CR
  2361. rjmp test_dxyz
Advertisement
Add Comment
Please, Sign In to add comment