prjbrook

forth85_05. Tidier.

Jul 15th, 2014
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.52 KB | None | 0 0
  1. ;this is forth85_05 .
  2.  
  3.  
  4. .NOLIST
  5. .include "tn85def.inc"
  6. .LIST
  7. .LISTMAC ;sometimes macro code gets in way of clarity in listing
  8. .MACRO header
  9. .db high(@0), low(@0), @1, @2
  10. .ENDMACRO
  11. .MACRO mypop
  12. ld @0,-y
  13. .ENDMACRO
  14. .MACRO mypush
  15. st y+, @0
  16. .ENDMACRO
  17. .MACRO mypop2
  18. mypop @0
  19. mypop @1
  20. .ENDMACRO
  21. .MACRO mypush2
  22. mypush @0
  23. mypush @1
  24. .ENDMACRO
  25.  
  26.  
  27. .def FOUND = r15 ;if found=1 we have a match of Ram word on dictionary
  28. .def BOTTOM = r14 ;have hit the bottom of the dict and not found a match
  29. .def STOP = r13 ;stop interpreting line of words
  30. .def STATE = r12
  31. .def FOUNDCOUNTER = r11 ;dealWithWord clicks this if found =1. Counts successful finds in dictionary.
  32. .def SECONDLETTER =r10 ;helpful for debugging
  33. .def vl = r22
  34. .def vh = r23 ; u,v,w,x,y,z are all pointers
  35. .DSEG
  36. .ORG 0x60
  37.  
  38. ;consts: .DB "jksdafhsdf",8, 255, 0b01010101, -128, 0xaa
  39. .equ BUF1LENGTH = 64
  40.  
  41. buf1: .byte BUF1LENGTH
  42. buf2: .byte 64 ;could have third buffer?
  43. varSpace: .byte 64 ;might need more than 32 variables
  44. ;.org 0x1E0
  45. myStackStart: .byte 64
  46.  
  47. .cseg
  48. .ORG 0x800 ;dictionary starts at 4K (2K words) mark
  49. ;----------------------------------------------------
  50. one_1:
  51. .db 0,0,3, "one" ;code for one
  52. one:
  53. ; rcall stackme
  54. rcall stackme_2
  55. .db 01, 00
  56. ret
  57. ;----------------------------------------------
  58. two_1:
  59. header one_1, 3, "two"
  60. two:
  61. rcall stackme_2
  62. .db 02,00
  63. ret
  64. ;------------------------------------------
  65. dup_1:
  66. header two_1,3,"dup"
  67. dup:
  68. mypop r17
  69. mypop r16
  70. mypush r16
  71. mypush r17
  72. mypush r16
  73. mypush r17
  74.  
  75. ret
  76. ;-------------------------------------------
  77. drop_1:
  78. header dup_1,4,"drop"
  79. drop:
  80. mypop r17
  81. mypop r16 ;TODO what if stack pointer goes thru floor?
  82. ret
  83. ;----------------------------------
  84. swapp_1: ;twp p's becasue assembler recognizes avr opcode swap
  85. header drop_1,5, "swapp"
  86. swapp:
  87. mypop2 r17,r16
  88. mypop2 r19,r18
  89. mypush2 r16,r17
  90. mypush2 r18,r19
  91. ret
  92.  
  93.  
  94. ;-------------------------------------------------
  95. LATEST: ;shift this later
  96.  
  97. S_1:
  98. ;the EOL token that gets put into end of buf1 to stop parsing
  99. header swapp_1,1,"S"
  100. S:
  101. clr STOP
  102. inc STOP ;set time-to-quit flag
  103. ret
  104. ;-------------------------------------------------
  105. stackme_2: ;stacks on my stack next 16bit num. Address of 16bit number is on SP-stack
  106. ; Used like this stackme_2 0034. Puts 0034 on myStack and increments past number on return stack.
  107. pop r17
  108. pop r16 ; they now contain eg 0x0804 which contain the 16bit num
  109. movw zl,r16 ;z now points to cell that cobtains the number
  110. clc
  111. rol zl
  112. rol zh ;double word address for z. lpm coming up
  113.  
  114.  
  115.  
  116. lpm r16,z+
  117. lpm r17,z+ ;now have 16bit number in r16,17
  118.  
  119. st y+,r16
  120. st y+, r17 ;mystack now contains the number
  121.  
  122. clc
  123. ror zh
  124. ror zl ;halve the z pointer to step past the number to return at the right place
  125.  
  126. push zl
  127. push zh
  128.  
  129. ret
  130.  
  131.  
  132.  
  133. ;====================================================================================================
  134.  
  135. .ORG 0
  136. rjmp start
  137. typein: .db " one two dup drop swapp ", 0x0d
  138.  
  139. ;stackme dropx onex stackme swap drop",0x0d
  140. start:
  141. ldi r16, low(RAMEND)
  142. out SPL, r16
  143. ldi r16,high(RAMEND)
  144. out SPH, r16
  145.  
  146. ldi YL,low(myStackStart)
  147. ldi YH,high(myStackStart)
  148.  
  149. rjmp test_interpretLine
  150.  
  151. rjmp start
  152.  
  153. getline0: ;force a line into buf1 via flash string. Simulates GETLINE
  154. ldi zl, low(typein<<1)
  155. ldi zh, high(typein<<1)
  156. ldi xl, low(buf1)
  157. ldi xh, high(buf1)
  158. type0:
  159. lpm r16,Z+
  160. st x+,r16
  161. cpi r16,0x0d ;have we got to the end of the line?
  162. brne type0
  163. ret
  164. ;--------------------------------------------
  165. ;WORD gets x to point to start of word (copy in w=r24,25) with the length in len = r20
  166. ;assume word points to somewhere in buf1. Should advance thru spaces=0x20 to first real char
  167. word: ;maybe give it a header later
  168. ld r16,x+ ;get char
  169. ld SECONDLETTER, x ;for debugging
  170.  
  171. cpi r16,0x20 ;is it a space?
  172. breq word ;if so get next char
  173. ;if here we're point to word start. so save this adr in w
  174. mov r24,xl
  175. mov r25,xh ;wordstart now saved in w
  176.  
  177.  
  178. clr r20 ;length initially 0
  179. nextchar:
  180. inc r20 ;r20 = word length
  181. ld r16,x+ ;get next char
  182. cpi r16,0x20
  183. brne nextchar
  184. dec r24 ;adjust start of word
  185. ;if here we've found a word.Starting at w length in r20.x points to space just past word
  186. ret
  187. ;----------------------------------------
  188.  
  189. 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.
  190. ; and the word in buf1 is pointed to by w=r24,25. len = r20. Z on entry points to the link. Needs +2 to
  191. lpm r23,z+
  192. lpm r22,z+ ;store next link in v=r22,23. z now points to len byte
  193.  
  194. startc:
  195. push r20 ;save length
  196. lpm r16,Z+ ;length of dictionary word, first entry now in r16
  197. cp r16,r20 ;same lengths?
  198. brne outcom ;not = so bail out
  199. ;if here the words are the same length, what about the rest of the chars.First get x to point to word.
  200. mov xl,r24
  201. mov xh,r25 ;x now point to start of buf1 word
  202. upcom:
  203. lpm r16,z+
  204. ld r17,x+ ;get one corresponding char from each word
  205. cp r16,r17 ;same word?
  206. brne outcom ;bail out if chars are different
  207. dec r20 ;count chars
  208. brne upcom ;still matching and not finished so keep going
  209. ;if here r20 is 0 so match must have been perfect so FOUND = 1
  210. clr FOUND
  211. inc FOUND
  212. outcom:
  213. pop r20 ;get old lngth of buf1 word back
  214. ret
  215. ;-------------------------------------------
  216. jmpNextWord: ;go to next word in the dictionary. Assume v=r22,23 contains next link word(not byte)
  217. ; and w = r24,25 contains RAM word start with len in r20
  218. ;exit with z pointing to next word ready for next COMPARE.
  219. clc
  220. rol r22
  221. rol r23 ;above 3 instructions change word address into byte address by doubling
  222. movw r30,r22 ;z now points to next word
  223. ret
  224. ;-----------------------------------------
  225.  
  226. doLatest: ;set up so first jump in dictionary is to top=LATEST and other flags set up.
  227. ldi vl, low(LATEST)
  228. ldi vh, high(LATEST)
  229. clr FOUND
  230. clr BOTTOM ;not yet found the match, not yet at the bottom. Either will stop search.
  231. clr STOP ;keep parsing words til this goes to a 1
  232. ret
  233. ;---------------------------------------------
  234. interpretLine: ;given line of words in buf one, search for words one by one. Don't do code
  235. ; or compile at this stage, just find and report that and go into next one.
  236. rcall getline0 ;change later to real getline via terminal
  237. rcall pasteEOL
  238. ldi xl, low(buf1)
  239. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  240. clr FOUNDCOUNTER ;counts finds in line parsing.
  241.  
  242. nextWord:
  243. tst STOP
  244. brne stopLine
  245. rcall word
  246. rcall findWord ;not done yet
  247. rcall dealWithWord ;go and run code STATE=0, or compile (STATE =1).{ c0de, comp1le}
  248. rjmp nextWord
  249. stopLine:
  250. ret
  251. ;-----------------------------------------------------------------
  252. findWord:
  253. rcall doLatest
  254. upjmpf:
  255. rcall jmpNextWord
  256. rcall compare
  257. tst FOUND
  258. brne stopsearchf ;if last compare got a match (FOUND=1) then stop searching
  259. tst vl
  260. brne upjmpf ;if v=0000 then we've hit the bottom of the dictionary
  261. tst vh
  262. brne upjmpf ;not found and not at bottom so keep going
  263. ;if here FOUND =0, ie no match yet and we've hit the bottom of the dictionary
  264. clr BOTTOM
  265. inc BOTTOM ;exit with FOUND=0 and BOTTOM =1
  266. stopsearchf: nop
  267. ret
  268. ;----------------------------
  269. test_interpretLine:
  270. rcall interpretLine
  271. til: rjmp til ;**
  272. ;------------------------------
  273. dealWithWord: ;come here when it's time to compile or run code
  274. ;Good debugging spot. Enter here with Z pointing to CFA of word found. Y points to myStack. X points to just
  275. ; 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
  276. ; to the next word in dic. Either just below the found word or 0000 if we get to the bottome with no match
  277. ;
  278. nop
  279. tst FOUND
  280. breq notfound
  281. inc FOUNDCOUNTER
  282.  
  283. ;want to hop over filler bytes,0's added to keep codes on even byte boundaries
  284. ; so if r30 is odd at this stage inc it. odd is lsbit = 1.
  285. sbrs r30,0 ;skip next instruction if final bit lsb = 1
  286. rjmp downdw
  287. ;if here lsb = 1 so we're on a padding byte and have to add 1 to get to a 2 byte boundary
  288. inc r30
  289. brcc downdw
  290. inc r31 ;add one to z before converting to bytes
  291.  
  292. downdw:
  293. clc
  294. ror zh
  295. ror zl ;put z back into word values
  296.  
  297.  
  298. rcall executeCode
  299.  
  300.  
  301.  
  302. .MESSAGE "Word found"
  303. rjmp outdww
  304. notfound:
  305. .MESSAGE "Word not found"
  306. clr STOP
  307. inc STOP ;stop parsing line
  308. outdww:
  309. ret
  310. ;------------------------------------------------------------------------
  311. pasteEOL: ;when a line of text is TYPEd into buf1 it should end with CR=$0d. This gets replaced with ]}, a
  312. ; special end of line word. When the word is invoked it casues a QUIT back to the waiting for input stage.
  313. ; Start at buf1 start and inspect each char for a $0D. When found replace with a "$20 S $20 "
  314. ldi xl, low(buf1)
  315. ldi xh, high(buf1) ;pnt to start of buffer
  316. clr r17
  317. nxtChar:
  318. inc r17 ;r17 is counter. Bail out when r17 > BUF1LENGTH
  319. cpi r17, BUF1LENGTH -4
  320. breq outProb
  321. ld r16, x+
  322. cpi r16, $0d
  323. brne nxtChar
  324. ;if here we've found a $0d in buf1 before the end, so replace with an EOL token. x points to just after it.
  325. ldi r16,$20
  326. st -x, r16 ;back up. Then go forward.
  327. ; ldi r16, ']'
  328. st x+, r16
  329. ldi r16,'S'
  330. st x+, r16
  331. ; ldi r16, '}'
  332. ; st x+, r16
  333. ldi r16, $20
  334. st x, r16
  335. rjmp outpel
  336.  
  337.  
  338. outProb:
  339. nop
  340. .MESSAGE "Couldn't find $0d"
  341. outpel:
  342. ret
  343.  
  344. ;-------------------------------------
  345. executeCode: ;with Z pointing to cfa. Not sure whether to jmp or call
  346.  
  347. ijmp
  348. ret
  349. ;---------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment