prjbrook

forth85_17 testing nums, words (not ;)

Aug 2nd, 2014
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 41.76 KB | None | 0 0
  1. ;this is forth85_17 Tidies up forth85_16
  2. ;getting ram dic working. Seem to have cracked compiling numbers into
  3. ; RAM dic. Now need some testing plus starting on ";" .
  4. ; testing seems OK now. ill push on with ; which sends ram dic back to
  5. ; flash dic (real one) and updates pointers
  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. .MACRO mypop
  14. ld @0,-y
  15. .ENDMACRO
  16. .MACRO mypush
  17. st y+, @0
  18. .ENDMACRO
  19. .MACRO mypop2
  20. mypop @0
  21. mypop @1
  22. .ENDMACRO
  23. .MACRO mypush2
  24. mypush @0
  25. mypush @1
  26. .ENDMACRO
  27. .MACRO pushx
  28. push xl
  29. push xh
  30. .ENDMACRO
  31. .MACRO popx
  32. pop xh
  33. pop xl
  34. .ENDMACRO
  35. .MACRO pushz
  36. push zl
  37. push zh
  38. .ENDMACRO
  39. .MACRO popz
  40. pop zh
  41. pop zl
  42. .ENDMACRO
  43. .MACRO mypopa ;call r16,17 the accumulator a, ditto for r18,r19 for b
  44. mypop r17
  45. mypop r16
  46. .ENDMACRO
  47. .MACRO mypopb
  48. mypop2 r19,r18
  49. .ENDMACRO
  50. .def mylatest =r2 ;r2,r3 is mylatest
  51. .def myhere =r4 ;r4,r5 is myhere. The pointer to flash copy in buf2.
  52. .def SOFPG=r6 ;start of flash page
  53. ;r6,r7 byte adr of flash page (11c0)
  54. ;r8,r9 (0012) offset when flash comes into buf2. r8 +E0 = myhere
  55. .def SECONDLETTER =r10 ;helpful for debugging
  56. .def FOUNDCOUNTER = r11 ;dealWithWord clicks this if found =1. Counts successful finds in dictionary.
  57. .def STATE = r12
  58. .def STOP = r13 ;stop interpreting line of words
  59. .def BOTTOM = r14 ;have hit the bottom of the dict and not found a match
  60. .def FOUND = r15 ;if found=1 we have a match of Ram word on dictionary
  61. ;r20 is length of word in WORD
  62. ;r21 is the flash length of word with immediate bit 8, if any, still there
  63.  
  64. .def vl = r22
  65. .def vh = r23 ; u,v,w,x,y,z are all pointers
  66. .def wl = r24 ;w=r24,25
  67. .def wh = r25
  68.  
  69. .DSEG
  70. .ORG 0x60
  71.  
  72. .equ BUF1LENGTH = 128
  73. .equ eHERE = $0010 ;eeprom adr of system varial eHere
  74. .equ eLATEST = $0012
  75.  
  76. buf1: .byte BUF1LENGTH ;input buffer. Lines max about 125
  77. buf2: .byte BUF1LENGTH ;this fits two flash buffers
  78. varSpace: .byte 64 ;might need more than 32 variables
  79. myStackStart: .byte 64 ;currently at $1E0.Meets return stack.
  80.  
  81. .CSEG
  82. .ORG 0x800 ;dictionary starts at 4K (2K words) mark
  83. ;----------------------------------------------------
  84. one_1:
  85. .db 0,0,3, "one" ;code for one
  86. one:
  87. ; rcall stackme
  88. rcall stackme_2
  89. .db 01, 00
  90. ret
  91. ;----------------------------------------------
  92. two_1:
  93. header one_1, 3, "two"
  94. two:
  95. rcall stackme_2
  96. .db 02,00
  97. ret
  98. ;------------------------------------------
  99. dup_1:
  100. header two_1,3,"dup"
  101. dup:
  102. mypop r17
  103. mypop r16
  104. mypush r16
  105. mypush r17
  106. mypush r16
  107. mypush r17
  108.  
  109. ret
  110. ;-------------------------------------------
  111. drop_1:
  112. header dup_1,4,"drop"
  113. drop:
  114. mypop r17
  115. mypop r16 ;TODO what if stack pointer goes thru floor?
  116. ret
  117. ;----------------------------------
  118. swapp_1: ;twp p's becasue assembler recognizes avr opcode swap
  119. header drop_1,5, "swapp"
  120. swapp:
  121. mypop2 r17,r16
  122. mypop2 r19,r18
  123. mypush2 r16,r17
  124. mypush2 r18,r19
  125. ret
  126.  
  127.  
  128. ;-------------------------------------------------
  129. ;shift this later
  130.  
  131. S_1:
  132. ;the EOL token that gets put into end of buf1 to stop parsing
  133. header swapp_1,$81,"S" ;NB always immediate
  134. S: ldi r16,02
  135. mov BOTTOM,r16 ;r14 =2 means a nice stop. EOL without errors
  136. clr STOP
  137. inc STOP ;set time-to-quit flag
  138. ret
  139. ;------------------------------------------
  140.  
  141. fetch_1: ;doesn't like label = @-1
  142. ;classic fetch. (adr -- num). Only in RAM
  143. header S_1,1,"@"
  144. fetch:
  145. pushx ;going to use x to point so better save
  146. mypop xh
  147. mypop xl
  148. ld r16,x+
  149. ld r17,x
  150. mypush r16
  151. mypush r17 ; and put them on my stack
  152. popx ;return with x intact and RAM val on my stack
  153. ret
  154. ;dddddddddddddddddddddddddddddddddddddddddddddddd
  155.  
  156. cfetch_1: ;doesn't like label = c@-1
  157. ;classic fetch. (adr -- num). Only in RAM. Do I want y to advance just one byte on mystack
  158. header fetch_1,2,"c@"
  159. cfetch:
  160. pushx ;going to use x to point so better save
  161. mypop xh
  162. mypop xl
  163. ld r16,x+
  164. mypush r16
  165. popx ;return with x intact and RAM val on my stack
  166. ret
  167. ;dddddddddddddddddddddddddddddddddddddddddddddddd
  168.  
  169. store_1: ;classic != "store"(adr num --) . Num is now at cell adr.
  170. header cfetch_1,1,"!"
  171. store:
  172. mypop2 r17,r16 ;there goes the num
  173. pushx
  174. mypop2 xh,xl ;there goes the address
  175. st x+,r16
  176. st x,r17 ;num goes to cell with location=adr
  177. popx
  178. ret
  179. ;ddddddddddddddddddddddddddddddddddddddddddddddddddd
  180.  
  181. cstore_1: ;classic c!= "store"(adr 8-bitnum --) . 8 bit Num is now at cell adr.
  182. header store_1,2,"c!"
  183. cstore:
  184. mypop r16 ;there goes the num. Just 8 bits at this stage.
  185. pushx
  186. mypop2 xh,xl ;there goes the address
  187. st x+,r16
  188. ; st x,r17 ;num goes to cell with location=adr
  189. popx
  190. ret
  191. ;------------------------------------
  192.  
  193. star_1: ;classic 16*16 mulitply (n n -- n*n)
  194. header cstore_1,1,"*"
  195. star:
  196. mypop2 r17,r16
  197. mypop2 r19,r18 ;now have both numbers in r16..r19
  198. rcall mpy16s ; multiply them. Result in r18..r21. Overflow in r20,21
  199. mypush2 r18,r19
  200. ret
  201. ;-----------------------------------------
  202.  
  203. slashMod_1: ;classic /MOD (n m -- n/m rem)
  204. header star_1,4,"/mod"
  205. slashMod:
  206. push r13
  207. push r14 ;this is STOP but is used by div16s, so better save it
  208. mypop2 r19,r18 ; that's m
  209. mypop2 r17,r16 ;that's n
  210. rcall div16s ;the the 16 by 16 bit divsion
  211. mypush2 r16,r17 ;answer ie n/m
  212. mypush2 r14,r15 ;remainder
  213. pop r14
  214. pop r13
  215. ret
  216. ;dddddddddddddddddddddddddddddddddddddddddddd
  217.  
  218. plus_1: ;classic + ( n n -- n+n)
  219. header slashMod_1,1,"+"
  220. plus:
  221. mypop2 r17,r16
  222. mypop2 r19,r18
  223. clc
  224. add r16,r18
  225. adc r17,r19
  226. mypush2 r16,r17
  227. ret
  228. ;--
  229.  
  230. minus_1: ;classic - ( n m -- n-m)
  231. header plus_1,1,"-"
  232. minus:
  233. mypop2 r19,r18
  234. mypop2 r17,r16
  235. clc
  236. sub r16,r18
  237. sbc r17,r19
  238. mypush2 r16,r17
  239. ret
  240. ;dddddddddddddddddddddddddddddddddddddddddd
  241.  
  242. pstore_1: ;expects eg. 0003 PORTB P! etc, "output 3 via PORTB"
  243. header minus_1,2, "p!"
  244. pstore:
  245. mypopb ;get rid of PORTB number, not used for tiny85, just one port
  246. mypopa ; this is used. it's eg the 003 = R16 above
  247. out PORTB,r16
  248. ret
  249. ;ddddddddddddddddddddddddd
  250.  
  251. portblabel_1:
  252. header pstore_1,5,"PORTB" ; note caps just a filler that point 0b in stack for dropping
  253. portblabel:
  254. ; Extend later on to include perhaps other ports
  255. ; one:
  256. ; rcall stackme
  257.  
  258. rcall stackme_2
  259. .db $0b, 00
  260. ret
  261. ;---------------------
  262.  
  263. datadirstore_1: ;set ddrb. invioked like this 000f PORTB dd! to make pb0..pb3 all outputs
  264. header portblabel_1, 3, "dd!"
  265. datadirstore:
  266. mypopb ; there goes useless 0b = PORTB
  267. mypopa ; 000f now in r17:16
  268. out DDRB,r16
  269. ret
  270. ;dddddddddddddddddddddddddddddddddddd
  271. ;sbilabel_1 ;set bit in PORTB. Just a kludge at this stage
  272. ;header datadirstore_1,3,"sbi" TODO sort out sbi and delay later. Now get on with compiler.
  273. ;first need store system vars in the eeprom. Arbitrarily 0010 is HERE and 0012 (in eeprom) is LATEST
  274. ;----------------------------------------
  275.  
  276. percentcstore_1: ;(n16 adr16 --) %c! stores stack val LSbyte to eeprom adr
  277. ; eg 10 00 1234 stores 34 to 0010 <--eeprom adr
  278. header datadirstore_1,3,"%c!"
  279. percentcstore:
  280. mypopb ;adr in r18,19
  281. mypopa ;data. Lower byte into r16
  282.  
  283. rcall eewritebyte ;burn it into eeprom
  284. ret
  285. ;----------------------------------
  286.  
  287. percentstore_1: ; (n16 adr16 --) b16 stored at eeprom adr adr16 and adr16+1
  288. header percentcstore_1,2, "%!"
  289. percentstore:
  290. mypopb ;adr in b=r18,19
  291. mypopa ;n16 into r16,17 as data
  292.  
  293. rcall eewritebyte ;burn low data byte
  294. clc
  295. inc r18
  296. brne outpcs
  297. inc r17 ;sets up adr+1 for next byte
  298. outpcs:
  299. mov r16,r17 ;r16 now conatins hi byte
  300. rcall eewritebyte
  301. ret
  302. ;-------------------------------
  303.  
  304. percentcfetch_1: ;(eepromadr16--char). Fetch eeprom byte at adr on stack
  305. header percentstore_1,3,"%c@"
  306. percentcfetch:
  307. mypopb ;adr now in r18,19
  308. rcall eereadbyte
  309. mypush r16 ; there's the char going on stack. Should be n16? Not n8?
  310. ret
  311. ;-------------------
  312.  
  313. percentfetch_1: ;(adr16--n16) get 16bits at adr and adr+1
  314. header percentcfetch_1,2,"%@"
  315. percentfetch:
  316. rcall percentcfetch ;low byte now on stack
  317. inc r18
  318. brcc downpf
  319. inc r19
  320. downpf:
  321. rcall eereadbyte ;there's the high byte hitting the mystack
  322. mypush r16
  323. ret
  324. ;-------------------------------
  325. gethere_1: ; leaves current value of eHERE on stack
  326. header percentfetch_1,7,"gethere"
  327. gethere:
  328. rcall stackme_2
  329. .dw eHere
  330. rcall percentfetch
  331. ret
  332. ;--------------------
  333.  
  334. getlatest_1: ;leaves current value of latest on stack
  335. header gethere_1,9, "getlatest"
  336. getlatest:
  337. rcall stackme_2
  338. .dw eLATEST ;the address of the latest link lives in eeprom at address 0012
  339. rcall percentfetch ;get the val out of eeprom
  340. ret
  341. ;------------------
  342.  
  343. colon_1: ;classic ":"compiling new word marker
  344. header getlatest_1,1,":"
  345. rcall coloncode
  346. ret
  347. ;----------------------------------------
  348.  
  349. comma_1: ;classic comma. ;Put adr on stack into dictionary at myhere and bump myhere
  350. header colon_1,1,","
  351. comma:
  352. mypopa ;adr now in r16,17
  353. pushz ;save z
  354. movw zl,myhere ;z now pnts to next avail space in dic
  355. st z+,r16
  356. st z+,r17
  357. movw myhere,zl ;so that myhere is updated as ptr
  358. popz ;bring z back
  359. ret
  360. ;------------------------------------
  361.  
  362. tic_1: ;clasic tic('). Put cfa of next word on stack
  363. header comma_1,1, "'"
  364. tic:
  365. rcall word ;point to next word in input
  366. rcall findword ;leaving cfa in z
  367. mypush2 zl,zh
  368. rcall two ;but it's in bytes. Need words so / by 2
  369. rcall slashmod
  370. rcall drop ;that's the remainder dropped
  371. ;now have cfa of word after ' on stack in word-units.
  372. ret
  373. ;-----------------------
  374.  
  375. dummy_1: ;handy debugging place to put a break point
  376. header tic_1,$85,"dummy" ;first immediate word
  377. dummy:
  378. nop
  379. ret
  380. ;--------------------------------
  381. LATEST:
  382. compstackme_2_1: ;needed infront of every number compiled
  383. header dummy_1, $0d,"compstackme_2"
  384. compstackme_2:
  385. ldi r16,low(stackme_2)
  386. ldi r17,high(stackme_2)
  387. mypush2 r16,r17 ;in words need to *2 to convert to bytes
  388. rcall two
  389. rcall star
  390. rcall compileme
  391. ret
  392. ;-----------------------------------------
  393. HERE:
  394. .db $12,$34, 6, "mxword"
  395. rcall stackme_2
  396. .dw $1234
  397. rcall two
  398. rcall stackme_2
  399. .dw $2468
  400.  
  401. rcall one
  402. rcall plus
  403. rcall dummy
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419. ;---------------stackme_2 used to live here----------------------------------
  420.  
  421.  
  422.  
  423.  
  424. ;====================================================================================================
  425.  
  426. .ORG 0
  427. rjmp start
  428. ;typein: .db "11bb 0014 %! getlatest",$0d, "0013 %@",0x0d
  429.  
  430. typein: .db " : myword 1234 two 2468 one + dummy " ,$0d
  431. ;"11bb 0014 %! ", $0d ;%! getlatest",$0d, "0013 %@",0x0d
  432. ;" one 0010 00ab %c! 0012 cdef %! 0013 %c@ 0013 %@ 0987 drop ", 0x0d
  433.  
  434. ;stackme dropx onex stackme swap drop",0x0d
  435. start:
  436. ldi r16, low(RAMEND)
  437. out SPL, r16
  438.  
  439.  
  440. ldi r16,high(RAMEND)
  441. out SPH, r16
  442.  
  443. ldi YL,low(myStackStart)
  444. ldi YH,high(myStackStart)
  445. rcall burneepromvars
  446.  
  447.  
  448. ;rjmp test_interpretLine
  449. ;rjmp test_cfetch
  450. ;rjmp test_store
  451. ;rjmp test_cstore
  452. ;rjmp test_mpy16s
  453. ;rjmp test_mpy16s0
  454. ;rjmp test_star
  455. ;rjmp test_div16s
  456. ;rjmp test_slashMod
  457. ;rjmp test_Hex4ToBin2
  458. rjmp test_interpretLine
  459. ;rjmp setupforflashin
  460. ;rcall coloncode
  461. ;zzz
  462.  
  463. stopper: rjmp stopper
  464. ; rjmp start
  465.  
  466. getline0: ;force a line into buf1 via flash string. Simulates GETLINE
  467. ldi zl, low(typein<<1)
  468. ldi zh, high(typein<<1)
  469. ldi xl, low(buf1)
  470. ldi xh, high(buf1)
  471. type0:
  472. lpm r16,Z+
  473. st x+,r16
  474. cpi r16,0x0d ;have we got to the end of the line?
  475. brne type0
  476. ret
  477. ;--------------------------------------------
  478. ;WORD gets x to point to start of word (copy in w=r24,25) with the length in len = r20
  479. ;assume word points to somewhere in buf1. Should advance thru spaces=0x20 to first real char
  480. word: ;maybe give it a header later
  481. ld r16,x+ ;get char
  482. ld SECONDLETTER, x ;for debugging
  483.  
  484. cpi r16,0x20 ;is it a space?
  485. breq word ;if so get next char
  486. ;if here we're point to word start. so save this adr in w
  487. mov r24,xl
  488. mov r25,xh ;wordstart now saved in w
  489.  
  490.  
  491. clr r20 ;length initially 0
  492. nextchar:
  493. inc r20 ;r20 = word length
  494. ld r16,x+ ;get next char
  495. cpi r16,0x20
  496. brne nextchar
  497. dec r24 ;adjust start of word
  498. ;if here we've found a word.Starting at w length in r20.x points to space just past word
  499. ret
  500. ;----------------------------------------
  501.  
  502. 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.
  503. ; and the word in buf1 is pointed to by w=r24,25. len = r20. Z on entry points to the link. Needs +2 to
  504. lpm r23,z+
  505. lpm r22,z+ ;store next link in v=r22,23. z now points to len byte
  506.  
  507. startc:
  508. ;TODO save copy of flash word in r21 and also do masking of immediates
  509. push r20 ;save length
  510. lpm r16,Z+ ;length of dictionary word, first entry now in r16
  511. mov r21,r16 ;copy length-in-flash to r21. May have immediate bit (bit 7)
  512. andi r16,$0f ;mask off top nibble before comparing
  513. cp r16,r20 ;same lengths?
  514. brne outcom ;not = so bail out
  515. ;if here the words are the same length, what about the rest of the chars.First get x to point to word.
  516. mov xl,r24
  517. mov xh,r25 ;x now point to start of buf1 word
  518. upcom:
  519. lpm r16,z+
  520. ld r17,x+ ;get one corresponding char from each word
  521. cp r16,r17 ;same word?
  522. brne outcom ;bail out if chars are different
  523. dec r20 ;count chars
  524. brne upcom ;still matching and not finished so keep going
  525. ;if here r20 is 0 so match must have been perfect so FOUND = 1
  526. clr FOUND
  527. inc FOUND
  528. outcom:
  529. pop r20 ;get old lngth of buf1 word back
  530. ret
  531. ;-------------------------------------------
  532. jmpNextWord: ;go to next word in the dictionary. Assume v=r22,23 contains next link word(not byte)
  533. ; and w = r24,25 contains RAM word start with len in r20
  534. ;exit with z pointing to next word ready for next COMPARE.
  535. clc
  536. rol r22
  537. rol r23 ;above 3 instructions change word address into byte address by doubling
  538. movw r30,r22 ;z now points to next word
  539. ret
  540. ;-----------------------------------------
  541.  
  542. doLatest: ;set up so first jump in dictionary is to top=LATEST and other flags set up.
  543. ldi vl, low(LATEST)
  544. ldi vh, high(LATEST)
  545. clr FOUND
  546. clr BOTTOM ;not yet found the match, not yet at the bottom. Either will stop search.
  547. clr STOP ;keep parsing words til this goes to a 1
  548. ret
  549. ;---------------------------------------------
  550. interpretLine: ;given line of words in buf one, search for words one by one. Don't do code
  551. ; or compile at this stage, just find and report that and go into next one.
  552. rcall getline0 ;change later to real getline via terminal
  553. rcall pasteEOL
  554. ldi xl, low(buf1)
  555. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  556. clr FOUNDCOUNTER ;counts finds in line parsing.
  557.  
  558. nextWord:
  559. tst STOP
  560. brne stopLine
  561. rcall word
  562. rcall findWord ;not done yet
  563. rcall dealWithWord ;go and run code STATE=0, or compile (STATE =1).{ c0de, comp1le}
  564. rjmp nextWord
  565. stopLine:
  566. ret
  567. ;-----------------------------------------------------------------
  568. findWord:
  569. rcall doLatest
  570. upjmpf:
  571. rcall jmpNextWord
  572. rcall compare
  573. tst FOUND
  574. brne stopsearchf ;if last compare got a match (FOUND=1) then stop searching
  575. tst vl
  576. brne upjmpf ;if v=0000 then we've hit the bottom of the dictionary
  577. tst vh
  578. brne upjmpf ;not found and not at bottom so keep going
  579. ;if here FOUND =0, ie no match yet and we've hit the bottom of the dictionary
  580. clr BOTTOM
  581. inc BOTTOM ;exit with FOUND=0 and BOTTOM =1
  582. stopsearchf: nop
  583. ret
  584. ;----------------------------
  585. test_interpretLine:
  586. rcall interpretLine
  587. til: rjmp til ;** with r24 pointing to 'S' and FOUND = r15 =1
  588. ;------------------------------
  589. dealWithWord: ;come here when it's time to compile or run code
  590. ;Good debugging spot. Enter here with Z pointing to CFA of word found. Y points to myStack. X points to just
  591. ; 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
  592. ; to the next word in dic. Either just below the found word or 0000 if we get to the bottome with no match
  593. ;
  594. nop
  595. tst FOUND
  596. breq notfound
  597. inc FOUNDCOUNTER
  598.  
  599. ;want to hop over filler bytes,0's added to keep codes on even byte boundaries
  600. ; so if r30 is odd at this stage inc it. odd is lsbit = 1.
  601. sbrs r30,0 ;skip next instruction if final bit lsb = 1
  602. rjmp downd
  603. ;if here lsb = 1 so we're on a padding byte and have to add 1 to get to a 2 byte boundary
  604. inc r30
  605. brcc downd
  606. inc r31 ;add one to z before converting to bytes
  607. ;have to ask at this point, is the word immediate? If so, bit 7 of r21 will be set.
  608. downd:
  609. sbrs r21,7
  610. rjmp downdw ;not immediate so just go on with STATE test
  611. rjmp executeme ;yes, immediate so execute every time.
  612.  
  613.  
  614. downdw: tst STATE
  615. breq executeme
  616. rcall compilecode
  617. rjmp outdww
  618. executeme:
  619. clc
  620. ror zh
  621. ror zl ;put z back into word values
  622.  
  623.  
  624. rcall executeCode
  625.  
  626.  
  627.  
  628. .MESSAGE "Word found"
  629. rjmp outdww
  630. notfound:
  631. nop
  632. ; .MESSAGE "Word not found"
  633. ; clr STOP
  634. ; inc STOP ;stop parsing line
  635. rcall numberh ; word not in dict so must be a number? Form = HHHH
  636. ;now have to add 3 to x so it points past this word ready not next one
  637. clc
  638. inc r26
  639. inc r26
  640. inc r26
  641. brcc outdww
  642. inc r27 ;but only if overflow
  643. nop
  644. outdww:
  645. ret ;with STOP =1 in not a number
  646. ;------------------------------------------------------------------------
  647. pasteEOL: ;when a line of text is TYPEd into buf1 it should end with CR=$0d. This gets replaced with ]}, a
  648. ; special end of line word. When the word is invoked it casues a QUIT back to the waiting for input stage.
  649. ; Start at buf1 start and inspect each char for a $0D. When found replace with a "$20 S $20 "
  650. ldi xl, low(buf1)
  651. ldi xh, high(buf1) ;pnt to start of buffer
  652. clr r17
  653. nxtChar:
  654. inc r17 ;r17 is counter. Bail out when r17 > BUF1LENGTH
  655. cpi r17, BUF1LENGTH -3
  656. breq outProb
  657. ld r16, x+
  658. cpi r16, $0d
  659. brne nxtChar
  660. ;if here we've found a $0d in buf1 before the end, so replace with an EOL token. x points to just after it.
  661. ldi r16,$20
  662. st -x, r16 ;back up. Then go forward.
  663. ; ldi r16, ']'
  664. st x+, r16
  665. ldi r16,'S'
  666. st x+, r16
  667. ; ldi r16, '}'
  668. ; st x+, r16
  669. ldi r16, $20
  670. st x, r16
  671. rjmp outpel
  672.  
  673.  
  674. outProb:
  675. nop
  676. .MESSAGE "Couldn't find $0d"
  677. outpel:
  678. ret
  679.  
  680. ;-------------------------------------
  681. executeCode: ;with Z pointing to cfa. Not sure whether to jmp or call
  682.  
  683. ijmp
  684. ret
  685. ;---------------------------------------
  686. test_fetch: ;do run thru of @
  687. rcall getline0 ;change later to real getline via terminal
  688. rcall pasteEOL
  689. ldi xl, low(buf1)
  690. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  691.  
  692. ldi r16,$62
  693. mypush r16
  694. ldi r16,$0
  695. mypush r16 ;should now have adr $0062 on mystack
  696. rcall fetch
  697. tf1:
  698. rjmp tf1
  699. ;---------------------------------
  700. test_cfetch: ;do run thru of @
  701. rcall getline0 ;change later to real getline via terminal
  702. rcall pasteEOL
  703. ldi xl, low(buf1)
  704. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  705.  
  706. ldi r16,$62
  707. mypush r16
  708. ldi r16,$0
  709. mypush r16 ;should now have adr $62 on mystack
  710. rcall cfetch
  711. tcf1:
  712. rjmp tcf1
  713. ;----------------------------
  714. test_store:
  715. rcall getline0 ;change later to real getline via terminal
  716. rcall pasteEOL
  717. ldi xl, low(buf1)
  718. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  719. ldi r16,$62
  720. ldi r17,$0
  721. mypush2 r16,r17 ;should now have adr $62 on mystack
  722. ldi r16, $AB
  723. ldi r17, $CD
  724. mypush2 r16,r17 ;now have $ABCD on mystack
  725. rcall store
  726. ts1:
  727. rjmp ts1
  728. ;------------------------
  729. test_cstore:
  730. rcall getline0 ;change later to real getline via terminal
  731. rcall pasteEOL
  732. ldi xl, low(buf1)
  733. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  734. ldi r16,$62
  735. ldi r17,$0
  736. mypush2 r16,r17 ;should now have adr $62 on mystack
  737. ldi r16, $AB
  738. ; ldi r17, $CD
  739. mypush r16 ;now have $ABCD on mystack
  740. rcall cstore
  741.  
  742. ts11:
  743. rjmp ts11
  744. ;Now put arith routines here. Are from AVR200. Just using 16*16 for * but get 32bit result.
  745.  
  746.  
  747. ;***************************************************************************
  748. ;*
  749. ;* "mpy16s" - 16x16 Bit Signed Multiplication
  750. ;*
  751. ;* This subroutine multiplies signed the two 16-bit register variables
  752. ;* mp16sH:mp16sL and mc16sH:mc16sL.
  753. ;* The result is placed in m16s3:m16s2:m16s1:m16s0.
  754. ;* The routine is an implementation of Booth's algorithm. If all 32 bits
  755. ;* in the result are needed, avoid calling the routine with
  756. ;* -32768 ($8000) as multiplicand
  757. ;*
  758. ;* Number of words :16 + return
  759. ;* Number of cycles :210/226 (Min/Max) + return
  760. ;* Low registers used :None
  761. ;* High registers used :7 (mp16sL,mp16sH,mc16sL/m16s0,mc16sH/m16s1,
  762. ;* m16s2,m16s3,mcnt16s)
  763. ;*
  764. ;***************************************************************************
  765.  
  766. ;***** Subroutine Register Variables
  767.  
  768. .def mc16sL =r16 ;multiplicand low byte
  769. .def mc16sH =r17 ;multiplicand high byte
  770. .def mp16sL =r18 ;multiplier low byte
  771. .def mp16sH =r19 ;multiplier high byte
  772. .def m16s0 =r18 ;result byte 0 (LSB)
  773. .def m16s1 =r19 ;result byte 1
  774. .def m16s2 =r20 ;result byte 2
  775. .def m16s3 =r21 ;result byte 3 (MSB)
  776. .def mcnt16s =r22 ;loop counter
  777.  
  778. ;***** Code
  779. mpy16s: clr m16s3 ;clear result byte 3
  780. sub m16s2,m16s2 ;clear result byte 2 and carry
  781. ldi mcnt16s,16 ;init loop counter
  782. m16s_1: brcc m16s_2 ;if carry (previous bit) set
  783. add m16s2,mc16sL ; add multiplicand Low to result byte 2
  784. adc m16s3,mc16sH ; add multiplicand High to result byte 3
  785. m16s_2: sbrc mp16sL,0 ;if current bit set
  786. sub m16s2,mc16sL ; sub multiplicand Low from result byte 2
  787. sbrc mp16sL,0 ;if current bit set
  788. sbc m16s3,mc16sH ; sub multiplicand High from result byte 3
  789. asr m16s3 ;shift right result and multiplier
  790. ror m16s2
  791. ror m16s1
  792. ror m16s0
  793. dec mcnt16s ;decrement counter
  794. brne m16s_1 ;if not done, loop more
  795. ret
  796. ;----------------------------------------------------------
  797. ;***** Multiply Two Signed 16-Bit Numbers (-12345*(-4321))
  798. test_mpy16s:
  799. ldi mc16sL,low(-12345)
  800. ldi mc16sH,high(-12345)
  801. ldi mp16sL,low(-4321)
  802. ldi mp16sH,high(-4321)
  803. rcall mpy16s ;result: m16s3:m16s2:m16s1:m16s0
  804. ;=$032df219 (53,342,745)
  805. tmpy: rjmp tmpy
  806.  
  807. test_mpy16s0:
  808. ldi mc16sL,low(123)
  809. ldi mc16sH,high(123)
  810. ldi mp16sL,low(147)
  811. ldi mp16sH,high(147)
  812. rcall mpy16s ;result: m16s3:m16s2:m16s1:m16s0
  813. tmpy0: rjmp tmpy0
  814. ;-----------------------
  815. test_star:
  816. ldi r16,-$7b
  817. mypush r16
  818. ldi r16,$00
  819. mypush r16 ;that's decimal 123 on stack
  820. ldi r16,$93
  821. mypush r16
  822. ldi r16,$00
  823. mypush r16 ; and thats dec'147
  824. rcall star
  825. tsr: rjmp tsr
  826.  
  827. ;--------------------------
  828. ;***************************************************************************
  829. ;*
  830. ;* "div16s" - 16/16 Bit Signed Division
  831. ;*
  832. ;* This subroutine divides signed the two 16 bit numbers
  833. ;* "dd16sH:dd16sL" (dividend) and "dv16sH:dv16sL" (divisor).
  834. ;* The result is placed in "dres16sH:dres16sL" and the remainder in
  835. ;* "drem16sH:drem16sL".
  836. ;*
  837. ;* Number of words :39
  838. ;* Number of cycles :247/263 (Min/Max)
  839. ;* Low registers used :3 (d16s,drem16sL,drem16sH)
  840. ;* High registers used :7 (dres16sL/dd16sL,dres16sH/dd16sH,dv16sL,dv16sH,
  841. ;* dcnt16sH)
  842. ;*
  843. ;***************************************************************************
  844.  
  845. ;***** Subroutine Register Variables
  846.  
  847. .def d16s =r13 ;sign register
  848. .def drem16sL=r14 ;remainder low byte
  849. .def drem16sH=r15 ;remainder high byte
  850. .def dres16sL=r16 ;result low byte
  851. .def dres16sH=r17 ;result high byte
  852. .def dd16sL =r16 ;dividend low byte
  853. .def dd16sH =r17 ;dividend high byte
  854. .def dv16sL =r18 ;divisor low byte
  855. .def dv16sH =r19 ;divisor high byte
  856. .def dcnt16s =r20 ;loop counter
  857.  
  858. ;***** Code
  859.  
  860. div16s: ;push r13 ;PB !!
  861. ;push r14 ;PB !!
  862. mov d16s,dd16sH ;move dividend High to sign register
  863. eor d16s,dv16sH ;xor divisor High with sign register
  864. sbrs dd16sH,7 ;if MSB in dividend set
  865. rjmp d16s_1
  866. com dd16sH ; change sign of dividend
  867. com dd16sL
  868. subi dd16sL,low(-1)
  869. sbci dd16sL,high(-1)
  870. d16s_1: sbrs dv16sH,7 ;if MSB in divisor set
  871. rjmp d16s_2
  872. com dv16sH ; change sign of divisor
  873. com dv16sL
  874. subi dv16sL,low(-1)
  875. sbci dv16sL,high(-1)
  876. d16s_2: clr drem16sL ;clear remainder Low byte
  877. sub drem16sH,drem16sH;clear remainder High byte and carry
  878. ldi dcnt16s,17 ;init loop counter
  879.  
  880. d16s_3: rol dd16sL ;shift left dividend
  881. rol dd16sH
  882. dec dcnt16s ;decrement counter
  883. brne d16s_5 ;if done
  884. sbrs d16s,7 ; if MSB in sign register set
  885. rjmp d16s_4
  886. com dres16sH ; change sign of result
  887. com dres16sL
  888. subi dres16sL,low(-1)
  889. sbci dres16sH,high(-1)
  890. d16s_4: ;pop r14 ;PB!!
  891. ;pop r13 ;PB!!
  892. ret ; return
  893. d16s_5: rol drem16sL ;shift dividend into remainder
  894. rol drem16sH
  895. sub drem16sL,dv16sL ;remainder = remainder - divisor
  896. sbc drem16sH,dv16sH ;
  897. brcc d16s_6 ;if result negative
  898. add drem16sL,dv16sL ; restore remainder
  899. adc drem16sH,dv16sH
  900. clc ; clear carry to be shifted into result
  901. rjmp d16s_3 ;else
  902. d16s_6: sec ; set carry to be shifted into result
  903. rjmp d16s_3
  904.  
  905. ;-----------------------------------------------
  906.  
  907. test_div16s:
  908. ;***** Divide Two Signed 16-Bit Numbers (-22,222/10)
  909. ldi dd16sL,low(-22222)
  910. ldi dd16sH,high(-22222)
  911. ldi dv16sL,low(10)
  912. ldi dv16sH,high(10)
  913. rcall div16s ;result: $f752 (-2222)
  914. ;remainder: $0002 (2)
  915.  
  916. forever:rjmp forever
  917. ;----------------------------------
  918. test_slashMod:
  919. ldi r16,$12
  920. mypush r16
  921. ldi r16,$34
  922. mypush r16
  923. ldi r16,$56 ;NB this is $3412 not $1234
  924. mypush r16
  925. ldi r16,$00
  926. mypush r16
  927. rcall slashMod ;$3412 / $56 = $9b rem 0 works
  928. tslm: rjmp tslm
  929.  
  930. ;---------------------------------------
  931. ;From http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#hex2bin
  932. ; Hex4ToBin2
  933. ; converts a 4-digit-hex-ascii to a 16-bit-binary
  934. ; In: Z points to first digit of a Hex-ASCII-coded number
  935. ; Out: T-flag has general result:
  936. ; T=0: rBin1H:L has the 16-bit-binary result, Z points
  937. ; to the first digit of the Hex-ASCII number
  938. ; T=1: illegal character encountered, Z points to the
  939. ; first non-hex-ASCII character
  940. ; Used registers: rBin1H:L (result), R0 (restored after
  941. ; use), rmp
  942. ; Called subroutines: Hex2ToBin1, Hex1ToBin1
  943.  
  944. .def rBin1H =r17
  945. .def rBin1L = r16
  946. .def rmp = r18
  947. ;
  948. Hex4ToBin2:
  949. clt ; Clear error flag
  950. rcall Hex2ToBin1 ; convert two digits hex to Byte
  951. brts Hex4ToBin2a ; Error, go back
  952. mov rBin1H,rmp ; Byte to result MSB
  953. rcall Hex2ToBin1 ; next two chars
  954. brts Hex4ToBin2a ; Error, go back
  955. mov rBin1L,rmp ; Byte to result LSB
  956. sbiw ZL,4 ; result ok, go back to start
  957. Hex4ToBin2a:
  958. ret
  959. ;
  960. ; Hex2ToBin1 converts 2-digit-hex-ASCII to 8-bit-binary
  961. ; Called By: Hex4ToBin2
  962. ;
  963. Hex2ToBin1:
  964. push R0 ; Save register
  965. rcall Hex1ToBin1 ; Read next char
  966. brts Hex2ToBin1a ; Error
  967. swap rmp; To upper nibble
  968. mov R0,rmp ; interim storage
  969. rcall Hex1ToBin1 ; Read another char
  970. brts Hex2ToBin1a ; Error
  971. or rmp,R0 ; pack the two nibbles together
  972. Hex2ToBin1a:
  973. pop R0 ; Restore R0
  974. ret ; and return
  975. ;
  976. ; Hex1ToBin1 reads one char and converts to binary
  977. ;
  978. Hex1ToBin1:
  979. ld rmp,z+ ; read the char
  980. subi rmp,'0' ; ASCII to binary
  981. brcs Hex1ToBin1b ; Error in char
  982. cpi rmp,10 ; A..F
  983. brcs Hex1ToBin1c ; not A..F
  984. cpi rmp,$30 ; small letters?
  985. brcs Hex1ToBin1a ; No
  986. subi rmp,$20 ; small to capital letters
  987. Hex1ToBin1a:
  988. subi rmp,7 ; A..F
  989. cpi rmp,10 ; A..F?
  990. brcs Hex1ToBin1b ; Error, is smaller than A
  991. cpi rmp,16 ; bigger than F?
  992. brcs Hex1ToBin1c ; No, digit ok
  993. Hex1ToBin1b: ; Error
  994. sbiw ZL,1 ; one back
  995. set ; Set flag
  996. Hex1ToBin1c:
  997. ret ; Return
  998. ;--------------------------------------
  999. test_Hex4ToBin2:
  1000. pushz
  1001. ldi zl,$60
  1002. clr zh ;z now points to start of buf1
  1003. ldi r16,'0'
  1004. st z+,r16
  1005. ldi r16,'f'
  1006. st z+,r16
  1007. ldi r16,'2'
  1008. st z+,r16
  1009. ldi r16,'3'
  1010. st z+,r16
  1011. ldi zl,$60
  1012. clr zh ;z now points back to start of buf1
  1013. rcall Hex4ToBin2
  1014. popz
  1015. th4: rjmp th4
  1016. ;-------------------------------------
  1017. numberh: ;word not in dictionary. Try to convert it to hex.
  1018. pushz ;algorithm uses z, pity
  1019. movw zl,r24 ;r4,25 = w holds start of current word
  1020. ;z now points eg to '12ab'start. If t=0 then it coverts to real hex
  1021. rcall hex4ToBin2 ;try to convert
  1022. ;above call needs 4 hex digits to emerge with t=0 and binary in r16,17
  1023. ;want this. If t=0 stack r16,17 and carry on interpreting, else emerge with
  1024. ; t=1 and zpointing to first problem char
  1025. brtc gotHex
  1026. ; if here there's a problem that z is pointing to. Bail out of interpret line
  1027. clr STOP
  1028. inc STOP
  1029. rjmp outnh
  1030.  
  1031. gotHex: ;sucess.Real hex in r16,17
  1032. mypush2 r16,r17 ; so push num onto mystack
  1033. ;maybe we're compiling. If so, push num into dic preceded by a call to stackme_2
  1034. tst STATE
  1035. breq outnh ;STATE =0 means executing
  1036. ; rcall tic
  1037. ; .db "stackme_2" ;has to be in dic before a number. cfa of stackme_2 on stack
  1038. rcall compstackme_2
  1039. ; rcall compileme ;insert "rcall stackme_2"opcode into dic
  1040. rcall comma ;there's the number going in
  1041.  
  1042. outnh:
  1043. popz ; but will it be pointing to "right"place in buf1? Yes now OK
  1044.  
  1045. ret
  1046. ; numberh not working fully, ie doesn't point to right place after action.
  1047. ; also no action if not a number? DONE better save this first.
  1048. ;---------------------------------
  1049. ;eeroutines
  1050. eewritebyte: ;write what's in r16 to eeprom adr in r18,19
  1051. sbic EECR,EEPE
  1052. rjmp eewritebyte ;keep looping til ready to write
  1053. ;if here the previous write is all done and we can write the next byte to eeprom
  1054. out EEARH,r19
  1055. out EEARL,r18 ;adr done
  1056. out EEDR,r16 ;byte in right place now
  1057. sbi EECR,EEMPE
  1058. sbi EECR,EEPE ;last 2 instruc write eprom. Takes 3.4 ms
  1059. ret
  1060. ;test with %!
  1061. ;---------------------------------
  1062. eereadbyte: ; read eeprom byte at adr in r18,19 into r16
  1063. ; Wait for completion of previous write
  1064. sbic EECR,EEPE
  1065. rjmp eereadbyte
  1066. ; Set up address (r18:r17) in address register
  1067. out EEARH, r19
  1068. out EEARL, r18
  1069. ; Start eeprom read by writing EERE
  1070. sbi EECR,EERE
  1071. ; Read data from data register
  1072. in r16,EEDR
  1073. ret
  1074. ;------------------------------
  1075. setupforflashin: ;using here etc get appropriate page, offset,myhere values.
  1076. ldi r16,low(HERE)
  1077. ldi r17,high(HERE) ;get here, but from eeprom better?
  1078. mypush2 r16,r17
  1079. rcall stackme_2
  1080. .dw 0002
  1081. rcall star ;now have current HERE in bytes in flash. But what is myhere?
  1082. rcall stackme_2
  1083. .db $0040 ;64 bytes per page
  1084. rcall slashMod
  1085. ;offset on top pagenum under. eg pg 0047, offset 0012
  1086. mypop2 r9,r8 ;store offset (in bytes)
  1087. rcall stackme_2
  1088. .db $0040
  1089. rcall star ;pgnum*64 = byte adr of start of flash page
  1090. mypop2 r7,r6
  1091. mypush2 r8,r9 ;push back offset
  1092. rcall stackme_2
  1093. .dw buf2
  1094. nop
  1095. ;at this stage we have offset in r8,r9 (0012). Also byte adr of flash page
  1096. ; start in r6,r7.(11c0) Stk is (offset buf2Start --) (0012 00E0 --). Need to
  1097. ; add these two together to get myhere, the pointer to RAM here position.
  1098. rcall plus ;add offset to buf2 start to get myhere (00f2)
  1099. ; put my here in r4,r5 for time being.
  1100. mypop2 r5,r4 ;contains eg 00f2 <--myhere
  1101. pushz ;going to use z so save it
  1102. movw zl,r6 ;r6,7 have byte adr of flsh pg strt
  1103. pushx ;save x
  1104. ldi xl,low(buf2)
  1105. ldi xh,high(buf2) ;point x to start of buf2
  1106. ldi r18,128 ;r18=ctr. Two flash pages = 128 bytes
  1107. upflash:
  1108. lpm r16,z+ ;get byte from flash page
  1109. st x+, r16 ; and put into buf2
  1110. dec r18
  1111. brne upflash
  1112. ;done. Now have two flash pages in ram in buf2. Myhere points to where next
  1113. ; entry will go. Where's page num?
  1114. popx
  1115. popz ;as if nothing happened
  1116.  
  1117.  
  1118. ret
  1119.  
  1120.  
  1121.  
  1122. ;outsufi: rjmp outsufi
  1123. ;-----------------------------------
  1124. burneepromvars: ;send latest versions of eHERE and eLATEST to eeprom
  1125. ldi r16,low(HERE)
  1126. ldi r17,high(HERE)
  1127. mypush2 r16,r17
  1128. ;up top we have .equ eHERE = $0010
  1129. ldi r16,low(eHERE)
  1130. ldi r17,high(eHERE)
  1131. mypush2 r16,r17
  1132. ;now have n16 eadr on stack ready for e!
  1133. rcall percentstore
  1134.  
  1135. ;send latest versions of eLATEST to eeprom
  1136. ldi r16,low(LATEST)
  1137. ldi r17,high(LATEST)
  1138. mypush2 r16,r17
  1139. ;up top we have .equ eLATEST = $0010
  1140. ldi r16,low(eLATEST)
  1141. ldi r17,high(eLATEST)
  1142. mypush2 r16,r17
  1143. ;now have n16 eadr on stack ready for e!
  1144. rcall percentstore
  1145. ret
  1146. ;-------------------------------------------
  1147. coloncode: ;this is the classic colon defining word.
  1148. rcall setupforflashin ;get all the relevant vars and bring in flash to buf2
  1149. rcall relinkcode ; insert link into first cell
  1150. rcall create ;compile word preceeded by length
  1151. rcall leftbrac ;set state to 1, we're compiling
  1152. ret ;now every word gets compiled until we hit ";"
  1153. ;-------------------------
  1154. relinkcode: ;put LATEST into where myhere is pointing and update ptr = myhere
  1155. ;also create mylatest
  1156. rcall getlatest ;now on stack
  1157. mypopa ;latest in r16,17
  1158. pushz ;better save z
  1159. movw mylatest,myhere ;mylatest <-- myhere
  1160. movw zl,myhere ;z now points to next available spot in buf2
  1161. st z+,r16
  1162. st z+,r17 ;now have new link in start of dic word
  1163. movw myhere,zl ;update myhere to point to length byte. (Not yet there.)
  1164. popz ;restore z
  1165. ret
  1166. ;-------------------------------------------------
  1167. create: ;put word after ":" into dictionary, aftyer link, preceeded by len
  1168. rcall word ;start with x pnting just after ":".End with len in r20, x pointing to
  1169. ; space just after word and start of word in w=r24,25
  1170. pushz ;save z. It's going to be used on ram dictionary
  1171. movw zl,myhere ;z now pnts to next spot in ram dic
  1172. st z+,r20 ; put len byte into ram dic
  1173. mov r18,r20 ;use r18 as ctr, don't wreck r20
  1174. pushx ;save x. It's going to be word ptr in buf1
  1175. movw xl,wl ;x now points to start of word. Going to be sent to buf2
  1176. sendbytes:
  1177. ld r16,x+ ;tx byte from buf1 to
  1178. st z+,r16 ; buf2
  1179. dec r18 ;repeat r20=r18=len times
  1180. brne sendbytes
  1181.  
  1182. sbrs r30,0 ;skip next instruction if final bit lsb = 1
  1183. rjmp downcr
  1184. ;if here lsb = 1 so we're on a padding byte and have to add 1 to get to a 2 byte boundary
  1185. clr r16
  1186. st z+,r16 ;insert padding byte
  1187. ;inc r30
  1188. ;brcc downcr
  1189. ;inc r31 ;add one to z before converting to bytes
  1190.  
  1191. downcr:
  1192. movw myhere,zl ;myhere now points to beyond word in dic
  1193. popx
  1194. popz
  1195. ret ;with word in dic
  1196. ;----------------------------------------------
  1197. leftbrac: ;classic turn on compiling
  1198. clr STATE
  1199. inc STATE ;state =1 ==> now compiling
  1200. ret
  1201. ;------------------------
  1202. compilecode: ;come here with STATE =1 ie compile, not execute. Want to put
  1203. ; eg rcall dup in code in dictionary but not to execute dup. If here
  1204. ; z points to byte address of word
  1205. mypush2 zl,zh
  1206. compileme:
  1207. mypush2 myhere,r5 ;push ptr to RAM dic
  1208. ;next is entry point for eg ' stackme2 already on stack and have to compile
  1209.  
  1210. ldi r16,low(buf2)
  1211. ldi r17,high(buf2) ;start of buf that conatins flash pg in RAM
  1212. mypush2 r16,r17
  1213. rcall minus ; myhere - buf2-start = offset in page
  1214. mypush2 SOFPG,r7 ;push start of flash page address
  1215. rcall plus ;SOFPG + offset = adr of next rcall in dic
  1216. ;if here we have two flash addresses on the stack. TOS = here. Next is there.
  1217. ;want to insert code for "rcall there w"hen I'm at here. eg current debugging indicates
  1218. ; here = $11EB and there is $1012 (cfa of "two"). First compute
  1219. ; relative branch "there - here -2". Then fiddle this val into the rcall opcode
  1220. rcall minus ;that;s there - here. Usu negative.
  1221. ;I got fffffffff..ffe27 for above vals. First mask off all those f's
  1222. rcall two ;stack a 2
  1223. rcall minus ;now have there-here -2 = fe24. When there,here in bytes.
  1224. mypopa ;bring fe26 into r16,17
  1225. clc
  1226. ror r17
  1227. ror r16 ;now a:= a/2
  1228. ldi r18,$ff
  1229. ldi r19,$0f ;mask
  1230. and r16,r18
  1231. and r17,r19
  1232. ; mypush2 r16,r17 ;now fe26 --> 0e26
  1233. ;the rcall opcode is Dxxx where xxx is the branch
  1234. ; mypopa ;bring fe26 into r16,17
  1235. ldi r19, $d0 ;mask
  1236. or r17,r19
  1237. mypush2 r16,r17 ;now have $de26 on stack which is (?) rcall two
  1238. rcall comma ;store this opcode into dic. myhere is ptr
  1239. ret
  1240. ;---------------------------
  1241. stackme_2: ;stacks on my stack next 16bit num. Address of 16bit number is on SP-stack
  1242. ; Used like this stackme_2 0034. Puts 0034 on myStack and increments past number on return stack.
  1243. pop r17
  1244. pop r16 ; they now contain eg 0x0804 which contain the 16bit num
  1245. movw zl,r16 ;z now points to cell that cobtains the number
  1246. clc
  1247. rol zl
  1248. rol zh ;double word address for z. lpm coming up
  1249.  
  1250.  
  1251.  
  1252. lpm r16,z+
  1253. lpm r17,z+ ;now have 16bit number in r16,17
  1254.  
  1255. st y+,r16
  1256. st y+, r17 ;mystack now contains the number
  1257.  
  1258. clc
  1259. ror zh
  1260. ror zl ;halve the z pointer to step past the number to return at the right place
  1261.  
  1262. push zl
  1263. push zh
  1264.  
  1265. ret
  1266. ;call two
  1267. ;nop
Advertisement
Add Comment
Please, Sign In to add comment