prjbrook

forth85_06. @,c@,!,c!

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