prjbrook

forth85_15A, tic comma compiling

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