prjbrook

forth85_16 compiling numbers

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