prjbrook

forth85_08 number start

Jul 16th, 2014
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.98 KB | None | 0 0
  1. ;this is forth85_08.
  2. ; this task to get number, at least the get hex version going. Start with asc to hex
  3. ; numberh is nearly working. Just stay with 4 char hex at this stage. ie all nums
  4. ; are of form HHHH eg 001A
  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.  
  43.  
  44. .def FOUND = r15 ;if found=1 we have a match of Ram word on dictionary
  45. .def BOTTOM = r14 ;have hit the bottom of the dict and not found a match
  46. .def STOP = r13 ;stop interpreting line of words
  47. .def STATE = r12
  48. .def FOUNDCOUNTER = r11 ;dealWithWord clicks this if found =1. Counts successful finds in dictionary.
  49. .def SECONDLETTER =r10 ;helpful for debugging
  50. .def vl = r22
  51. .def vh = r23 ; u,v,w,x,y,z are all pointers
  52. .DSEG
  53. .ORG 0x60
  54.  
  55. ;consts: .DB "jksdafhsdf",8, 255, 0b01010101, -128, 0xaa
  56. .equ BUF1LENGTH = 64
  57.  
  58. buf1: .byte BUF1LENGTH
  59. buf2: .byte 64 ;could have third buffer?
  60. varSpace: .byte 64 ;might need more than 32 variables
  61. ;.org 0x1E0
  62. myStackStart: .byte 64
  63.  
  64. .cseg
  65. .ORG 0x800 ;dictionary starts at 4K (2K words) mark
  66. ;----------------------------------------------------
  67. one_1:
  68. .db 0,0,3, "one" ;code for one
  69. one:
  70. ; rcall stackme
  71. rcall stackme_2
  72. .db 01, 00
  73. ret
  74. ;----------------------------------------------
  75. two_1:
  76. header one_1, 3, "two"
  77. two:
  78. rcall stackme_2
  79. .db 02,00
  80. ret
  81. ;------------------------------------------
  82. dup_1:
  83. header two_1,3,"dup"
  84. dup:
  85. mypop r17
  86. mypop r16
  87. mypush r16
  88. mypush r17
  89. mypush r16
  90. mypush r17
  91.  
  92. ret
  93. ;-------------------------------------------
  94. drop_1:
  95. header dup_1,4,"drop"
  96. drop:
  97. mypop r17
  98. mypop r16 ;TODO what if stack pointer goes thru floor?
  99. ret
  100. ;----------------------------------
  101. swapp_1: ;twp p's becasue assembler recognizes avr opcode swap
  102. header drop_1,5, "swapp"
  103. swapp:
  104. mypop2 r17,r16
  105. mypop2 r19,r18
  106. mypush2 r16,r17
  107. mypush2 r18,r19
  108. ret
  109.  
  110.  
  111. ;-------------------------------------------------
  112. ;shift this later
  113.  
  114. S_1:
  115. ;the EOL token that gets put into end of buf1 to stop parsing
  116. header swapp_1,1,"S"
  117. S:
  118. clr STOP
  119. inc STOP ;set time-to-quit flag
  120. ret
  121. ;------------------------------------------
  122.  
  123. fetch_1: ;doesn't like label = @-1
  124. ;classic fetch. (adr -- num). Only in RAM
  125. header S_1,1,"@"
  126. fetch:
  127. pushx ;going to use x to point so better save
  128. mypop xh
  129. mypop xl
  130. ld r16,x+
  131. ld r17,x
  132. mypush r16
  133. mypush r17 ; and put them on my stack
  134. popx ;return with x intact and RAM val on my stack
  135. ret
  136. ;dddddddddddddddddddddddddddddddddddddddddddddddd
  137.  
  138. cfetch_1: ;doesn't like label = c@-1
  139. ;classic fetch. (adr -- num). Only in RAM. Do I want y to advance just one byte on mystack
  140. header fetch_1,2,"c@"
  141. cfetch:
  142. pushx ;going to use x to point so better save
  143. mypop xh
  144. mypop xl
  145. ld r16,x+
  146. mypush r16
  147. popx ;return with x intact and RAM val on my stack
  148. ret
  149. ;dddddddddddddddddddddddddddddddddddddddddddddddd
  150.  
  151. store_1: ;classic != "store"(adr num --) . Num is now at cell adr.
  152. header cfetch_1,1,"!"
  153. store:
  154. mypop2 r17,r16 ;there goes the num
  155. pushx
  156. mypop2 xh,xl ;there goes the address
  157. st x+,r16
  158. st x,r17 ;num goes to cell with location=adr
  159. popx
  160. ret
  161. ;ddddddddddddddddddddddddddddddddddddddddddddddddddd
  162.  
  163. cstore_1: ;classic c!= "store"(adr 8-bitnum --) . 8 bit Num is now at cell adr.
  164. header store_1,2,"c!"
  165. cstore:
  166. mypop r16 ;there goes the num. Just 8 bits at this stage.
  167. pushx
  168. mypop2 xh,xl ;there goes the address
  169. st x+,r16
  170. ; st x,r17 ;num goes to cell with location=adr
  171. popx
  172. ret
  173. ;------------------------------------
  174.  
  175. star_1: ;classic 16*16 mulitply (n n -- n*n)
  176. header cstore_1,1,"*"
  177. star:
  178. mypop2 r17,r16
  179. mypop2 r19,r18 ;now have both numbers in r16..r19
  180. rcall mpy16s ; multiply them. Result in r18..r21. Overflow in r20,21
  181. mypush2 r18,r19
  182. ret
  183. ;-----------------------------------------
  184. LATEST:
  185. slashMod_1: ;classic /MOD (n m -- n/m rem)
  186. header star_1,4,"/mod"
  187. slashMod:
  188. mypop2 r19,r18 ; that's m
  189. mypop2 r17,r16 ;that's n
  190. rcall div16s ;the the 16 by 16 bit divsion
  191. mypush2 r16,r17 ;answer ie n/m
  192. mypush2 r14,r15 ;remainder
  193. ret
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. ;-------------------------------------------------
  201. stackme_2: ;stacks on my stack next 16bit num. Address of 16bit number is on SP-stack
  202. ; Used like this stackme_2 0034. Puts 0034 on myStack and increments past number on return stack.
  203. pop r17
  204. pop r16 ; they now contain eg 0x0804 which contain the 16bit num
  205. movw zl,r16 ;z now points to cell that cobtains the number
  206. clc
  207. rol zl
  208. rol zh ;double word address for z. lpm coming up
  209.  
  210.  
  211.  
  212. lpm r16,z+
  213. lpm r17,z+ ;now have 16bit number in r16,17
  214.  
  215. st y+,r16
  216. st y+, r17 ;mystack now contains the number
  217.  
  218. clc
  219. ror zh
  220. ror zl ;halve the z pointer to step past the number to return at the right place
  221.  
  222. push zl
  223. push zh
  224.  
  225. ret
  226.  
  227.  
  228.  
  229. ;====================================================================================================
  230.  
  231. .ORG 0
  232. rjmp start
  233. typein: .db " one two 1234 ", 0x0d
  234.  
  235. ;stackme dropx onex stackme swap drop",0x0d
  236. start:
  237. ldi r16, low(RAMEND)
  238. out SPL, r16
  239. ldi r16,high(RAMEND)
  240. out SPH, r16
  241.  
  242. ldi YL,low(myStackStart)
  243. ldi YH,high(myStackStart)
  244.  
  245. ;rjmp test_interpretLine
  246. ;rjmp test_cfetch
  247. ;rjmp test_store
  248. ;rjmp test_cstore
  249. ;rjmp test_mpy16s
  250. ;rjmp test_mpy16s0
  251. ;rjmp test_star
  252. ;rjmp test_div16s
  253. ;rjmp test_slashMod
  254. ;rjmp test_Hex4ToBin2
  255. rjmp test_interpretLine
  256.  
  257. rjmp start
  258.  
  259. getline0: ;force a line into buf1 via flash string. Simulates GETLINE
  260. ldi zl, low(typein<<1)
  261. ldi zh, high(typein<<1)
  262. ldi xl, low(buf1)
  263. ldi xh, high(buf1)
  264. type0:
  265. lpm r16,Z+
  266. st x+,r16
  267. cpi r16,0x0d ;have we got to the end of the line?
  268. brne type0
  269. ret
  270. ;--------------------------------------------
  271. ;WORD gets x to point to start of word (copy in w=r24,25) with the length in len = r20
  272. ;assume word points to somewhere in buf1. Should advance thru spaces=0x20 to first real char
  273. word: ;maybe give it a header later
  274. ld r16,x+ ;get char
  275. ld SECONDLETTER, x ;for debugging
  276.  
  277. cpi r16,0x20 ;is it a space?
  278. breq word ;if so get next char
  279. ;if here we're point to word start. so save this adr in w
  280. mov r24,xl
  281. mov r25,xh ;wordstart now saved in w
  282.  
  283.  
  284. clr r20 ;length initially 0
  285. nextchar:
  286. inc r20 ;r20 = word length
  287. ld r16,x+ ;get next char
  288. cpi r16,0x20
  289. brne nextchar
  290. dec r24 ;adjust start of word
  291. ;if here we've found a word.Starting at w length in r20.x points to space just past word
  292. ret
  293. ;----------------------------------------
  294.  
  295. 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.
  296. ; and the word in buf1 is pointed to by w=r24,25. len = r20. Z on entry points to the link. Needs +2 to
  297. lpm r23,z+
  298. lpm r22,z+ ;store next link in v=r22,23. z now points to len byte
  299.  
  300. startc:
  301. push r20 ;save length
  302. lpm r16,Z+ ;length of dictionary word, first entry now in r16
  303. cp r16,r20 ;same lengths?
  304. brne outcom ;not = so bail out
  305. ;if here the words are the same length, what about the rest of the chars.First get x to point to word.
  306. mov xl,r24
  307. mov xh,r25 ;x now point to start of buf1 word
  308. upcom:
  309. lpm r16,z+
  310. ld r17,x+ ;get one corresponding char from each word
  311. cp r16,r17 ;same word?
  312. brne outcom ;bail out if chars are different
  313. dec r20 ;count chars
  314. brne upcom ;still matching and not finished so keep going
  315. ;if here r20 is 0 so match must have been perfect so FOUND = 1
  316. clr FOUND
  317. inc FOUND
  318. outcom:
  319. pop r20 ;get old lngth of buf1 word back
  320. ret
  321. ;-------------------------------------------
  322. jmpNextWord: ;go to next word in the dictionary. Assume v=r22,23 contains next link word(not byte)
  323. ; and w = r24,25 contains RAM word start with len in r20
  324. ;exit with z pointing to next word ready for next COMPARE.
  325. clc
  326. rol r22
  327. rol r23 ;above 3 instructions change word address into byte address by doubling
  328. movw r30,r22 ;z now points to next word
  329. ret
  330. ;-----------------------------------------
  331.  
  332. doLatest: ;set up so first jump in dictionary is to top=LATEST and other flags set up.
  333. ldi vl, low(LATEST)
  334. ldi vh, high(LATEST)
  335. clr FOUND
  336. clr BOTTOM ;not yet found the match, not yet at the bottom. Either will stop search.
  337. clr STOP ;keep parsing words til this goes to a 1
  338. ret
  339. ;---------------------------------------------
  340. interpretLine: ;given line of words in buf one, search for words one by one. Don't do code
  341. ; or compile at this stage, just find and report that and go into next one.
  342. rcall getline0 ;change later to real getline via terminal
  343. rcall pasteEOL
  344. ldi xl, low(buf1)
  345. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  346. clr FOUNDCOUNTER ;counts finds in line parsing.
  347.  
  348. nextWord:
  349. tst STOP
  350. brne stopLine
  351. rcall word
  352. rcall findWord ;not done yet
  353. rcall dealWithWord ;go and run code STATE=0, or compile (STATE =1).{ c0de, comp1le}
  354. rjmp nextWord
  355. stopLine:
  356. ret
  357. ;-----------------------------------------------------------------
  358. findWord:
  359. rcall doLatest
  360. upjmpf:
  361. rcall jmpNextWord
  362. rcall compare
  363. tst FOUND
  364. brne stopsearchf ;if last compare got a match (FOUND=1) then stop searching
  365. tst vl
  366. brne upjmpf ;if v=0000 then we've hit the bottom of the dictionary
  367. tst vh
  368. brne upjmpf ;not found and not at bottom so keep going
  369. ;if here FOUND =0, ie no match yet and we've hit the bottom of the dictionary
  370. clr BOTTOM
  371. inc BOTTOM ;exit with FOUND=0 and BOTTOM =1
  372. stopsearchf: nop
  373. ret
  374. ;----------------------------
  375. test_interpretLine:
  376. rcall interpretLine
  377. til: rjmp til ;**
  378. ;------------------------------
  379. dealWithWord: ;come here when it's time to compile or run code
  380. ;Good debugging spot. Enter here with Z pointing to CFA of word found. Y points to myStack. X points to just
  381. ; 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
  382. ; to the next word in dic. Either just below the found word or 0000 if we get to the bottome with no match
  383. ;
  384. nop
  385. tst FOUND
  386. breq notfound
  387. inc FOUNDCOUNTER
  388.  
  389. ;want to hop over filler bytes,0's added to keep codes on even byte boundaries
  390. ; so if r30 is odd at this stage inc it. odd is lsbit = 1.
  391. sbrs r30,0 ;skip next instruction if final bit lsb = 1
  392. rjmp downdw
  393. ;if here lsb = 1 so we're on a padding byte and have to add 1 to get to a 2 byte boundary
  394. inc r30
  395. brcc downdw
  396. inc r31 ;add one to z before converting to bytes
  397.  
  398. downdw:
  399. clc
  400. ror zh
  401. ror zl ;put z back into word values
  402.  
  403.  
  404. rcall executeCode
  405.  
  406.  
  407.  
  408. .MESSAGE "Word found"
  409. rjmp outdww
  410. notfound:
  411. .MESSAGE "Word not found"
  412. clr STOP
  413. inc STOP ;stop parsing line
  414. outdww:
  415. ret
  416. ;------------------------------------------------------------------------
  417. pasteEOL: ;when a line of text is TYPEd into buf1 it should end with CR=$0d. This gets replaced with ]}, a
  418. ; special end of line word. When the word is invoked it casues a QUIT back to the waiting for input stage.
  419. ; Start at buf1 start and inspect each char for a $0D. When found replace with a "$20 S $20 "
  420. ldi xl, low(buf1)
  421. ldi xh, high(buf1) ;pnt to start of buffer
  422. clr r17
  423. nxtChar:
  424. inc r17 ;r17 is counter. Bail out when r17 > BUF1LENGTH
  425. cpi r17, BUF1LENGTH -4
  426. breq outProb
  427. ld r16, x+
  428. cpi r16, $0d
  429. brne nxtChar
  430. ;if here we've found a $0d in buf1 before the end, so replace with an EOL token. x points to just after it.
  431. ldi r16,$20
  432. st -x, r16 ;back up. Then go forward.
  433. ; ldi r16, ']'
  434. st x+, r16
  435. ldi r16,'S'
  436. st x+, r16
  437. ; ldi r16, '}'
  438. ; st x+, r16
  439. ldi r16, $20
  440. st x, r16
  441. rjmp outpel
  442.  
  443.  
  444. outProb:
  445. nop
  446. .MESSAGE "Couldn't find $0d"
  447. outpel:
  448. ret
  449.  
  450. ;-------------------------------------
  451. executeCode: ;with Z pointing to cfa. Not sure whether to jmp or call
  452.  
  453. ijmp
  454. ret
  455. ;---------------------------------------
  456. test_fetch: ;do run thru of @
  457. rcall getline0 ;change later to real getline via terminal
  458. rcall pasteEOL
  459. ldi xl, low(buf1)
  460. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  461.  
  462. ldi r16,$62
  463. mypush r16
  464. ldi r16,$0
  465. mypush r16 ;should now have adr $0062 on mystack
  466. rcall fetch
  467. tf1:
  468. rjmp tf1
  469. ;---------------------------------
  470. test_cfetch: ;do run thru of @
  471. rcall getline0 ;change later to real getline via terminal
  472. rcall pasteEOL
  473. ldi xl, low(buf1)
  474. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  475.  
  476. ldi r16,$62
  477. mypush r16
  478. ldi r16,$0
  479. mypush r16 ;should now have adr $62 on mystack
  480. rcall cfetch
  481. tcf1:
  482. rjmp tcf1
  483. ;----------------------------
  484. test_store:
  485. rcall getline0 ;change later to real getline via terminal
  486. rcall pasteEOL
  487. ldi xl, low(buf1)
  488. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  489. ldi r16,$62
  490. ldi r17,$0
  491. mypush2 r16,r17 ;should now have adr $62 on mystack
  492. ldi r16, $AB
  493. ldi r17, $CD
  494. mypush2 r16,r17 ;now have $ABCD on mystack
  495. rcall store
  496. ts1:
  497. rjmp ts1
  498. ;------------------------
  499. test_cstore:
  500. rcall getline0 ;change later to real getline via terminal
  501. rcall pasteEOL
  502. ldi xl, low(buf1)
  503. ldi xh,high(buf1) ;last 3 statemnts are done onece. Now the main loop.
  504. ldi r16,$62
  505. ldi r17,$0
  506. mypush2 r16,r17 ;should now have adr $62 on mystack
  507. ldi r16, $AB
  508. ; ldi r17, $CD
  509. mypush r16 ;now have $ABCD on mystack
  510. rcall cstore
  511.  
  512. ts11:
  513. rjmp ts11
  514. ;Now put arith routines here. Are from AVR200. Just using 16*16 for * but get 32bit result.
  515.  
  516.  
  517. ;***************************************************************************
  518. ;*
  519. ;* "mpy16s" - 16x16 Bit Signed Multiplication
  520. ;*
  521. ;* This subroutine multiplies signed the two 16-bit register variables
  522. ;* mp16sH:mp16sL and mc16sH:mc16sL.
  523. ;* The result is placed in m16s3:m16s2:m16s1:m16s0.
  524. ;* The routine is an implementation of Booth's algorithm. If all 32 bits
  525. ;* in the result are needed, avoid calling the routine with
  526. ;* -32768 ($8000) as multiplicand
  527. ;*
  528. ;* Number of words :16 + return
  529. ;* Number of cycles :210/226 (Min/Max) + return
  530. ;* Low registers used :None
  531. ;* High registers used :7 (mp16sL,mp16sH,mc16sL/m16s0,mc16sH/m16s1,
  532. ;* m16s2,m16s3,mcnt16s)
  533. ;*
  534. ;***************************************************************************
  535.  
  536. ;***** Subroutine Register Variables
  537.  
  538. .def mc16sL =r16 ;multiplicand low byte
  539. .def mc16sH =r17 ;multiplicand high byte
  540. .def mp16sL =r18 ;multiplier low byte
  541. .def mp16sH =r19 ;multiplier high byte
  542. .def m16s0 =r18 ;result byte 0 (LSB)
  543. .def m16s1 =r19 ;result byte 1
  544. .def m16s2 =r20 ;result byte 2
  545. .def m16s3 =r21 ;result byte 3 (MSB)
  546. .def mcnt16s =r22 ;loop counter
  547.  
  548. ;***** Code
  549. mpy16s: clr m16s3 ;clear result byte 3
  550. sub m16s2,m16s2 ;clear result byte 2 and carry
  551. ldi mcnt16s,16 ;init loop counter
  552. m16s_1: brcc m16s_2 ;if carry (previous bit) set
  553. add m16s2,mc16sL ; add multiplicand Low to result byte 2
  554. adc m16s3,mc16sH ; add multiplicand High to result byte 3
  555. m16s_2: sbrc mp16sL,0 ;if current bit set
  556. sub m16s2,mc16sL ; sub multiplicand Low from result byte 2
  557. sbrc mp16sL,0 ;if current bit set
  558. sbc m16s3,mc16sH ; sub multiplicand High from result byte 3
  559. asr m16s3 ;shift right result and multiplier
  560. ror m16s2
  561. ror m16s1
  562. ror m16s0
  563. dec mcnt16s ;decrement counter
  564. brne m16s_1 ;if not done, loop more
  565. ret
  566. ;----------------------------------------------------------
  567. ;***** Multiply Two Signed 16-Bit Numbers (-12345*(-4321))
  568. test_mpy16s:
  569. ldi mc16sL,low(-12345)
  570. ldi mc16sH,high(-12345)
  571. ldi mp16sL,low(-4321)
  572. ldi mp16sH,high(-4321)
  573. rcall mpy16s ;result: m16s3:m16s2:m16s1:m16s0
  574. ;=$032df219 (53,342,745)
  575. tmpy: rjmp tmpy
  576.  
  577. test_mpy16s0:
  578. ldi mc16sL,low(123)
  579. ldi mc16sH,high(123)
  580. ldi mp16sL,low(147)
  581. ldi mp16sH,high(147)
  582. rcall mpy16s ;result: m16s3:m16s2:m16s1:m16s0
  583. tmpy0: rjmp tmpy0
  584. ;-----------------------
  585. test_star:
  586. ldi r16,-$7b
  587. mypush r16
  588. ldi r16,$00
  589. mypush r16 ;that's decimal 123 on stack
  590. ldi r16,$93
  591. mypush r16
  592. ldi r16,$00
  593. mypush r16 ; and thats dec'147
  594. rcall star
  595. tsr: rjmp tsr
  596.  
  597. ;--------------------------
  598. ;***************************************************************************
  599. ;*
  600. ;* "div16s" - 16/16 Bit Signed Division
  601. ;*
  602. ;* This subroutine divides signed the two 16 bit numbers
  603. ;* "dd16sH:dd16sL" (dividend) and "dv16sH:dv16sL" (divisor).
  604. ;* The result is placed in "dres16sH:dres16sL" and the remainder in
  605. ;* "drem16sH:drem16sL".
  606. ;*
  607. ;* Number of words :39
  608. ;* Number of cycles :247/263 (Min/Max)
  609. ;* Low registers used :3 (d16s,drem16sL,drem16sH)
  610. ;* High registers used :7 (dres16sL/dd16sL,dres16sH/dd16sH,dv16sL,dv16sH,
  611. ;* dcnt16sH)
  612. ;*
  613. ;***************************************************************************
  614.  
  615. ;***** Subroutine Register Variables
  616.  
  617. .def d16s =r13 ;sign register
  618. .def drem16sL=r14 ;remainder low byte
  619. .def drem16sH=r15 ;remainder high byte
  620. .def dres16sL=r16 ;result low byte
  621. .def dres16sH=r17 ;result high byte
  622. .def dd16sL =r16 ;dividend low byte
  623. .def dd16sH =r17 ;dividend high byte
  624. .def dv16sL =r18 ;divisor low byte
  625. .def dv16sH =r19 ;divisor high byte
  626. .def dcnt16s =r20 ;loop counter
  627.  
  628. ;***** Code
  629.  
  630. div16s: mov d16s,dd16sH ;move dividend High to sign register
  631. eor d16s,dv16sH ;xor divisor High with sign register
  632. sbrs dd16sH,7 ;if MSB in dividend set
  633. rjmp d16s_1
  634. com dd16sH ; change sign of dividend
  635. com dd16sL
  636. subi dd16sL,low(-1)
  637. sbci dd16sL,high(-1)
  638. d16s_1: sbrs dv16sH,7 ;if MSB in divisor set
  639. rjmp d16s_2
  640. com dv16sH ; change sign of divisor
  641. com dv16sL
  642. subi dv16sL,low(-1)
  643. sbci dv16sL,high(-1)
  644. d16s_2: clr drem16sL ;clear remainder Low byte
  645. sub drem16sH,drem16sH;clear remainder High byte and carry
  646. ldi dcnt16s,17 ;init loop counter
  647.  
  648. d16s_3: rol dd16sL ;shift left dividend
  649. rol dd16sH
  650. dec dcnt16s ;decrement counter
  651. brne d16s_5 ;if done
  652. sbrs d16s,7 ; if MSB in sign register set
  653. rjmp d16s_4
  654. com dres16sH ; change sign of result
  655. com dres16sL
  656. subi dres16sL,low(-1)
  657. sbci dres16sH,high(-1)
  658. d16s_4: ret ; return
  659. d16s_5: rol drem16sL ;shift dividend into remainder
  660. rol drem16sH
  661. sub drem16sL,dv16sL ;remainder = remainder - divisor
  662. sbc drem16sH,dv16sH ;
  663. brcc d16s_6 ;if result negative
  664. add drem16sL,dv16sL ; restore remainder
  665. adc drem16sH,dv16sH
  666. clc ; clear carry to be shifted into result
  667. rjmp d16s_3 ;else
  668. d16s_6: sec ; set carry to be shifted into result
  669. rjmp d16s_3
  670.  
  671. ;-----------------------------------------------
  672.  
  673. test_div16s:
  674. ;***** Divide Two Signed 16-Bit Numbers (-22,222/10)
  675. ldi dd16sL,low(-22222)
  676. ldi dd16sH,high(-22222)
  677. ldi dv16sL,low(10)
  678. ldi dv16sH,high(10)
  679. rcall div16s ;result: $f752 (-2222)
  680. ;remainder: $0002 (2)
  681.  
  682. forever:rjmp forever
  683. ;----------------------------------
  684. test_slashMod:
  685. ldi r16,$12
  686. mypush r16
  687. ldi r16,$34
  688. mypush r16
  689. ldi r16,$56 ;NB this is $3412 not $1234
  690. mypush r16
  691. ldi r16,$00
  692. mypush r16
  693. rcall slashMod ;$3412 / $56 = $9b rem 0 works
  694. tslm: rjmp tslm
  695.  
  696. ;---------------------------------------
  697. ;From http://www.avr-asm-tutorial.net/avr_en/calc/CONVERT.html#hex2bin
  698. ; Hex4ToBin2
  699. ; converts a 4-digit-hex-ascii to a 16-bit-binary
  700. ; In: Z points to first digit of a Hex-ASCII-coded number
  701. ; Out: T-flag has general result:
  702. ; T=0: rBin1H:L has the 16-bit-binary result, Z points
  703. ; to the first digit of the Hex-ASCII number
  704. ; T=1: illegal character encountered, Z points to the
  705. ; first non-hex-ASCII character
  706. ; Used registers: rBin1H:L (result), R0 (restored after
  707. ; use), rmp
  708. ; Called subroutines: Hex2ToBin1, Hex1ToBin1
  709.  
  710. .def rBin1H =r17
  711. .def rBin1L = r16
  712. .def rmp = r18
  713. ;
  714. Hex4ToBin2:
  715. clt ; Clear error flag
  716. rcall Hex2ToBin1 ; convert two digits hex to Byte
  717. brts Hex4ToBin2a ; Error, go back
  718. mov rBin1H,rmp ; Byte to result MSB
  719. rcall Hex2ToBin1 ; next two chars
  720. brts Hex4ToBin2a ; Error, go back
  721. mov rBin1L,rmp ; Byte to result LSB
  722. sbiw ZL,4 ; result ok, go back to start
  723. Hex4ToBin2a:
  724. ret
  725. ;
  726. ; Hex2ToBin1 converts 2-digit-hex-ASCII to 8-bit-binary
  727. ; Called By: Hex4ToBin2
  728. ;
  729. Hex2ToBin1:
  730. push R0 ; Save register
  731. rcall Hex1ToBin1 ; Read next char
  732. brts Hex2ToBin1a ; Error
  733. swap rmp; To upper nibble
  734. mov R0,rmp ; interim storage
  735. rcall Hex1ToBin1 ; Read another char
  736. brts Hex2ToBin1a ; Error
  737. or rmp,R0 ; pack the two nibbles together
  738. Hex2ToBin1a:
  739. pop R0 ; Restore R0
  740. ret ; and return
  741. ;
  742. ; Hex1ToBin1 reads one char and converts to binary
  743. ;
  744. Hex1ToBin1:
  745. ld rmp,z+ ; read the char
  746. subi rmp,'0' ; ASCII to binary
  747. brcs Hex1ToBin1b ; Error in char
  748. cpi rmp,10 ; A..F
  749. brcs Hex1ToBin1c ; not A..F
  750. cpi rmp,$30 ; small letters?
  751. brcs Hex1ToBin1a ; No
  752. subi rmp,$20 ; small to capital letters
  753. Hex1ToBin1a:
  754. subi rmp,7 ; A..F
  755. cpi rmp,10 ; A..F?
  756. brcs Hex1ToBin1b ; Error, is smaller than A
  757. cpi rmp,16 ; bigger than F?
  758. brcs Hex1ToBin1c ; No, digit ok
  759. Hex1ToBin1b: ; Error
  760. sbiw ZL,1 ; one back
  761. set ; Set flag
  762. Hex1ToBin1c:
  763. ret ; Return
  764. ;--------------------------------------
  765. test_Hex4ToBin2:
  766. pushz
  767. ldi zl,$60
  768. clr zh ;z now points to start of buf1
  769. ldi r16,'0'
  770. st z+,r16
  771. ldi r16,'f'
  772. st z+,r16
  773. ldi r16,'2'
  774. st z+,r16
  775. ldi r16,'3'
  776. st z+,r16
  777. ldi zl,$60
  778. clr zh ;z now points back to start of buf1
  779. rcall Hex4ToBin2
  780. popz
  781. th4: rjmp th4
  782. ;-------------------------------------
  783. numberh: ;word not in dictionary. Try to convert it to hex.
  784. pushz ;algorithm uses z, pity
  785. movw zl,r24 ;r4,25 = w holds start of current word
  786. ;z now points eg to '12ab'start. If t=0 then it coverts to real hex
  787. rcall hex4ToBin2 ;try to convert
  788. ;above call needs 4 hex digits to emerge with t=0 and binary in r16,17
  789. ;want this. If t=0 stack r16,17 and carry on interpreting, else emerge with
  790. ; t=1 and zpointing to first problem char
  791. brtc gotHex
  792. ; if here there's a problem that z is pointing to. Bail out of interpret line
  793. clr STOP
  794. inc STOP
  795. rjmp outnh
  796.  
  797. gotHex: ;sucess.Real hex in r16,17
  798. popz ; but will it be pointing to "right"place in buf1?
  799. outnh:
  800. ret
  801. ; numberh not working fully, ie doesn't point to right place after action.
  802. ; also no action if not a number? TODO better save this first.
Advertisement
Add Comment
Please, Sign In to add comment