prjbrook

Tiny 85, Forth85_04

Jul 14th, 2014
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.37 KB | None | 0 0
  1. ;this is forth85_04 .Got simple lines like "one two $0d. interpreted OK. Now going to work on drop, swap and rot.
  2. ; Got slowed up by need to change z from and to word.byte addresses. Also stackme_2 was difficult.
  3. ; Needs tidy up in nomenclature and old testing subroutines.
  4.  
  5. ;this is forth85_01. Just getting a few words in dictionary
  6. .NOLIST
  7. .include "tn85def.inc"
  8. .LIST
  9. ;.LISTMAC ;sometimes macro code gets in way of clarity in listing
  10. .MACRO header
  11. .db high(@0), low(@0), @1, @2
  12. .ENDMACRO
  13. .def FOUND = r15 ;if found=1 we have a match of Ram word on dictionary
  14. .def BOTTOM = r14 ;have hit the bottom of the dict and not found a match
  15. .def STOP = r13 ;stop interpreting line of words
  16. .def STATE = r12
  17. .def FOUNDCOUNTER = r11 ;dealWithWord clicks this if found =1. Counts successful finds in dictionary.
  18. .def SECONDLETTER =r10 ;helpful for debugging
  19. .def vl = r22
  20. .def vh = r23 ; u,v,w,x,y,z are all pointers
  21. .DSEG
  22. .ORG 0x60
  23.  
  24. ;consts: .DB "jksdafhsdf",8, 255, 0b01010101, -128, 0xaa
  25. .equ BUF1LENGTH = 64
  26.  
  27. buf1: .byte BUF1LENGTH
  28. buf2: .byte 64 ;could have third buffer?
  29. varSpace: .byte 64 ;might need more than 32 variables
  30. ;.org 0x1E0
  31. myStackStart: .byte 64
  32.  
  33. .cseg
  34. .ORG 0x800 ;dictionary starts at 4K (2K words) mark
  35. ;----------------------------------------------------
  36. one_1:
  37. .db 0,0,3, "one" ;code for one
  38. one:
  39. ; rcall stackme
  40. rcall stackme_2
  41. .db 01, 00
  42. ret
  43. ;----------------------------------------------
  44. stackme_1:
  45. .db high(one_1),low(one_1),7, "stackme" ; sp points to number to be stacked
  46. stackme:
  47. pop r17
  48. pop r16 ;low byte in low register
  49. st y+,r16
  50. st y+,r17 ;number now on mystack
  51. inc r16
  52. inc r16 ;add 2 to SP return address
  53. brcc finsm
  54. inc r17 ;if r16 overflowed
  55. push r17
  56. push r16 ;now point past number
  57. finsm:
  58. ret ;with number on mystack and ret adr just past it.
  59. ;--------------------------------------------
  60. two_1:
  61. header stackme_1, 3, "two"
  62. two:
  63. rcall stackme_2
  64. .db 02,00
  65. ret
  66. ;------------------------------------------
  67. dup_1:
  68. header two_1,3,"dup"
  69. dup:
  70. pop r16
  71. pop r17
  72. push r17
  73. push r16
  74. push r17
  75. push r16
  76. ret
  77. ;-------------------------------------------
  78. drop_1:
  79. header dup_1,4,"drop"
  80. drop:
  81. pop r16
  82. pop r17
  83. ret
  84. ;----------------------------------
  85. swapp_1: ;twp p's becasue assembler recognizes avr opcode swap
  86. header drop_1,5, "swapp"
  87. swapp:
  88. rcall drop
  89. pop r18
  90. pop r19
  91. push r17
  92. push r16
  93. push r19
  94. push r18
  95. ret
  96. ;-------------------------------------------------
  97. LATEST: ;shift this later
  98.  
  99. S_1:
  100. ;the EOL token that gets put into end of buf1 to stop parsing
  101. header swapp_1,1,"S"
  102. S:
  103. clr STOP
  104. inc STOP ;set time-to-quit flag
  105. ret
  106. ;-------------------------------------------------
  107. stackme_2: ;stacks on my stack next 16bit num. Address of 16bit number is on SP-stack
  108. ; Used like this stackme_2 0034. Puts 0034 on myStack and increments past number on return stack.
  109. pop r17
  110. pop r16 ; they now contain eg 0x0804 which contain the 16bit num
  111. movw zl,r16 ;z now points to cell that cobtains the number
  112. clc
  113. rol zl
  114. rol zh ;double word address for z. lpm coming up
  115.  
  116.  
  117.  
  118. lpm r16,z+
  119. lpm r17,z+ ;now have 16bit number in r16,17
  120.  
  121. st y+,r16
  122. st y+, r17 ;mystack now contains the number
  123.  
  124. clc
  125. ror zh
  126. ror zl ;halve the z pointer to step past the number to return at the right place
  127.  
  128. push zl
  129. push zh
  130.  
  131. ret
  132.  
  133.  
  134.  
  135. ;====================================================================================================
  136.  
  137. .ORG 0
  138. rjmp start
  139. typein: .db " one two", 0x0d
  140.  
  141. ;stackme dropx onex stackme swap drop",0x0d
  142. start:
  143. ldi r16, low(RAMEND)
  144. out SPL, r16
  145. ldi r16,high(RAMEND)
  146. out SPH, r16
  147.  
  148. ldi YL,low(myStackStart)
  149. ldi YH,high(myStackStart)
  150. ; ldi xl, low(consts)
  151. ; ldi xh, high(consts)
  152. ; ld r16, x+ ;why?
  153. ;rjmp test_getline0
  154. ;rjmp test_word
  155. ;rjmp test_compare
  156. ;rjmp test_jmpNextWord
  157. ;rjmp test_doLatest
  158. ;rjmp test_find
  159. rjmp test_interpretLine
  160. ;rjmp test_pasteEOL
  161. ;rjmp test_executeCode
  162.  
  163. rjmp start
  164.  
  165. getline0: ;force a line into buf1 via flash string. Simulates GETLINE
  166. ldi zl, low(typein<<1)
  167. ldi zh, high(typein<<1)
  168. ldi xl, low(buf1)
  169. ldi xh, high(buf1)
  170. type0:
  171. lpm r16,Z+
  172. st x+,r16
  173. cpi r16,0x0d ;have we got to the end of the line?
  174. brne type0
  175. ret
  176. ;--------------------------------------------
  177. test_getline0:
  178. rcall getline0
  179. heretgl:
  180. rjmp heretgl
  181. ;---------------------------------------
  182. ;WORD gets x to point to start of word (copy in w=r24,25) with the length in len = r20
  183. ;assume word points to somewhere in buf1. Should advance thru spaces=0x20 to first real char
  184. word: ;maybe give it a header later
  185. ld r16,x+ ;get char
  186. ld SECONDLETTER, x ;for debugging
  187.  
  188. cpi r16,0x20 ;is it a space?
  189. breq word ;if so get next char
  190. ;if here we're point to word start. so save this adr in w
  191. mov r24,xl
  192. mov r25,xh ;wordstart now saved in w
  193.  
  194.  
  195. clr r20 ;length initially 0
  196. nextchar:
  197. inc r20 ;r20 = word length
  198. ld r16,x+ ;get next char
  199. cpi r16,0x20
  200. brne nextchar
  201. dec r24 ;adjust start of word
  202. ;if here we've found a word.Starting at w length in r20.x points to space just past word
  203. ret
  204. ;----------------------------------------
  205. test_word:
  206. rcall getline0
  207. ldi xl, low(buf1)
  208. ldi xh, high(buf1)
  209. rcall word
  210. tw1:
  211. rjmp tw1
  212. ;-----------------------------------------
  213. find: ;maybe do a header later.
  214. ;Give a word from buf1 starting at w=r24,25, length r20. Is there a match in the dictionary?
  215. ;Start with z pointing to LATEST, which is the lngth of the first word in the dictionary.
  216.  
  217. ;find calls compare each tim it lands on a word.Exit with found = yes/no 1/0
  218. ;-------------
  219. 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.
  220. ; and the word in buf1 is pointed to by w=r24,25. len = r20. Z on entry points to the link. Needs +2 to
  221. lpm r23,z+
  222. lpm r22,z+ ;store next link in v=r22,23. z now points to len byte
  223.  
  224. ; inc zl
  225. ; inc zl ;step over link
  226. ; brcc startc
  227. ; inc zh ;only if zl overflows
  228. startc:
  229. push r20 ;save length
  230. lpm r16,Z+ ;length of dictionary word, first entry now in r16
  231. cp r16,r20 ;same lengths?
  232. brne outcom ;not = so bail out
  233. ;if here the words are the same length, what about the rest of the chars.First get x to point to word.
  234. mov xl,r24
  235. mov xh,r25 ;x now point to start of buf1 word
  236. upcom:
  237. lpm r16,z+
  238. ld r17,x+ ;get one corresponding char from each word
  239. cp r16,r17 ;same word?
  240. brne outcom ;bail out if chars are different
  241. dec r20 ;count chars
  242. brne upcom ;still matching and not finished so keep going
  243. ;if here r20 is 0 so match must have been perfect so FOUND = 1
  244. clr FOUND
  245. inc FOUND
  246. outcom:
  247. pop r20 ;get old lngth of buf1 word back
  248. ret
  249. ;-------------------------------------------
  250. test_compare:
  251. rcall getline0
  252. ldi xl, low(buf1)
  253. ldi xh, high(buf1)
  254. rcall word
  255. ldi zl, low(LATEST<<1)
  256. ldi zh, high(LATEST<<1)
  257. rcall compare
  258. tc0: rjmp tc0
  259. ;---------------------------------------
  260. jmpNextWord: ;go to next word in the dictionary. Assume v=r22,23 contains next link word(not byte)
  261. ; and w = r24,25 contains RAM word start with len in r20
  262. ;exit with z pointing to next word ready for next COMPARE.
  263. clc
  264. rol r22
  265. rol r23 ;above 3 instructions change word address into byte address by doubling
  266. movw r30,r22 ;z now points to next word
  267. ret
  268. ;-----------------------------------------
  269. test_jmpNextWord:
  270. rcall getline0
  271. ldi xl, low(buf1)
  272. ldi xh, high(buf1)
  273. rcall word
  274. ldi zl, low(LATEST<<1)
  275. ldi zh, high(LATEST<<1)
  276. rcall compare
  277. rcall jmpNextWord ;next put COMPARE after this. Then use FOUND in a loop
  278. rcall compare
  279. rcall jmpNextWord
  280. rcall compare
  281. rcall jmpNextWord
  282. rcall compare
  283. tjn: rjmp tjn
  284. ;--------------------------------------------------
  285. doLatest: ;set up so first jump in dictionary is to top=LATEST and other flags set up.
  286. ldi vl, low(LATEST)
  287. ldi vh, high(LATEST)
  288. clr FOUND
  289. clr BOTTOM ;not yet found the match, not yet at the bottom. Either will stop search.
  290. clr STOP ;keep parsing words til this goes to a 1
  291. ret
  292. ;---------------------------------------------
  293. test_doLatest:
  294. rcall getline0
  295. ldi xl, low(buf1)
  296. ldi xh, high(buf1)
  297. rcall word
  298. rcall doLatest
  299. rcall jmpNextWord ;
  300. rcall compare
  301. rcall jmpNextWord
  302. rcall compare
  303. rcall jmpNextWord
  304. rcall compare
  305.  
  306. tdl:
  307. rjmp tdl
  308. ;---------------------------------------------------
  309. test_find: ;set up for find then exit with either BOTTOM or FOUND =1
  310. rcall getline0
  311. ldi xl, low(buf1)
  312. ldi xh, high(buf1)
  313. rcall word
  314. rcall doLatest
  315. upjmp:
  316. rcall jmpNextWord
  317. rcall compare
  318. tst FOUND
  319. brne stopsearch ;if last compare got a match (FOUND=1) then stop searching
  320. tst vl
  321. brne upjmp ;if v=0000 then we've hit the bottom of the dictionary
  322. tst vh
  323. brne upjmp ;not found and not at bottom so keep going
  324. ;if here FOUND =0, ie no match yet and we've hit the bottom of the dictionary
  325. clr BOTTOM
  326. inc BOTTOM ;exit with FOUND=0 and BOTTOM =1
  327. stopsearch: nop
  328. rjmp stopsearch ;emerges, if FOUND=1, with Z pointing first executable code (often rcall ...)
  329. ;-----------------------------------------------------------
  330. interpretLine: ;given line of words in buf one, search for words one by one. Don't do code
  331. ; or compile at this stage, just find and report that and go into next one.
  332. rcall getline0 ;change later to real getline via terminal
  333. rcall pasteEOL
  334. ldi xl, low(buf1)
  335. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  336. clr FOUNDCOUNTER ;counts finds in line parsing.
  337.  
  338. nextWord:
  339. tst STOP
  340. brne stopLine
  341. rcall word
  342. rcall findWord ;not done yet
  343. rcall dealWithWord ;go and run code STATE=0, or compile (STATE =1).{ c0de, comp1le}
  344. rjmp nextWord
  345. stopLine:
  346. ret
  347. ;-----------------------------------------------------------------
  348. findWord:
  349. rcall doLatest
  350. upjmpf:
  351. rcall jmpNextWord
  352. rcall compare
  353. tst FOUND
  354. brne stopsearchf ;if last compare got a match (FOUND=1) then stop searching
  355. tst vl
  356. brne upjmpf ;if v=0000 then we've hit the bottom of the dictionary
  357. tst vh
  358. brne upjmpf ;not found and not at bottom so keep going
  359. ;if here FOUND =0, ie no match yet and we've hit the bottom of the dictionary
  360. clr BOTTOM
  361. inc BOTTOM ;exit with FOUND=0 and BOTTOM =1
  362. stopsearchf: nop
  363. ret
  364. ;----------------------------
  365. test_interpretLine:
  366. rcall interpretLine
  367. til: rjmp til
  368. ;------------------------------
  369. dealWithWord: ;come here when it's time to compile or run code
  370. ;Good dugging spot. Enter here with Z pointing to CFA of word found. Y points to myStack. X points to just
  371. ; 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
  372. ; to the next word in dic. Either just below the found word or 0000 if we get to the bottome with no match
  373. ;
  374. nop
  375. tst FOUND
  376. breq notfound
  377. inc FOUNDCOUNTER
  378.  
  379. ;scary
  380.  
  381. ; clc
  382. ; rol zl
  383. ; rol zh
  384. clc
  385. ror zh
  386. ror zl ;put z back into word values
  387.  
  388.  
  389. rcall executeCode
  390.  
  391.  
  392.  
  393. .MESSAGE "Word found"
  394. rjmp outdww
  395. notfound:
  396. .MESSAGE "Word not found"
  397. clr STOP
  398. inc STOP ;stop parsing line
  399. outdww:
  400. ret
  401. ;------------------------------------------------------------------------
  402. pasteEOL: ;when a line of text is TYPEd into buf1 it should end with CR=$0d. This gets replaced with ]}, a
  403. ; special end of line word. When the word is invoked it casues a QUIT back to the waiting for input stage.
  404. ; Start at buf1 start and inspect each char for a $0D. When found replace with a "$20 S $20 "
  405. ldi xl, low(buf1)
  406. ldi xh, high(buf1) ;pnt to start of buffer
  407. clr r17
  408. nxtChar:
  409. inc r17 ;r17 is counter. Bail out when r17 > BUF1LENGTH
  410. cpi r17, BUF1LENGTH -4
  411. breq outProb
  412. ld r16, x+
  413. cpi r16, $0d
  414. brne nxtChar
  415. ;if here we've found a $0d in buf1 before the end, so replace with an EOL token. x points to just after it.
  416. ldi r16,$20
  417. st -x, r16 ;back up. Then go forward.
  418. ; ldi r16, ']'
  419. st x+, r16
  420. ldi r16,'S'
  421. st x+, r16
  422. ; ldi r16, '}'
  423. ; st x+, r16
  424. ldi r16, $20
  425. st x, r16
  426. rjmp outpel
  427.  
  428.  
  429. outProb:
  430. nop
  431. .MESSAGE "Couldn't find $0d"
  432. outpel:
  433. ret
  434. ;-------------------------------------------
  435. test_pasteEOL:
  436. rcall getline0
  437. rcall pasteEOL
  438. teol:
  439. rjmp teol
  440. ;-------------------------------------
  441. executeCode: ;with Z pointing to cfa. Not sure whether to jmp or call
  442. ; ldi zh,$08 ;point to "one"
  443. ;
  444.  
  445.  
  446.  
  447. ijmp
  448. ret
  449. ;---------------------------------------
  450. test_executeCode: ;seems to ok ok with LIT
  451. rcall executeCode
  452. nop
  453. nop
  454.  
  455. tec: rjmp tec
Advertisement
Add Comment
Please, Sign In to add comment