Advertisement
NovaYoshi

Koei-inspired C machine

Oct 19th, 2018
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.62 KB | None | 0 0
  1. Registers:
  2. SP (stack pointer): 16-bit
  3. FP (frame pointer): 16-bit
  4. PC (program counter): 16-bit
  5. A (left reg) 16-bit (or 32-bit)
  6. B (right reg) 16-bit (or 32-bit)
  7. 8-bit and 16-bit loads clear the top 16 bits, if present
  8.  
  9. Addressing modes:
  10. <fast> = FP + item from lookup table
  11. <near> = FP + 8-bit sign extended offset
  12. <far> = FP + 16-bit offset
  13. <abs> = 16-bit address
  14.  
  15. Fast stack reference:
  16. Code | location | assembler name
  17. -----+----------+----------------
  18. 0 | frame-24 | local12
  19. 1 | frame-22 | local11
  20. 2 | frame-20 | local10
  21. 3 | frame-18 | local9
  22. 4 | frame-16 | local8
  23. 5 | frame-14 | local7
  24. 6 | frame-12 | local6
  25. 7 | frame-10 | local5
  26. 8 | frame-8 | local4
  27. 9 | frame-6 | local3
  28. A | frame-4 | local2
  29. B | frame-2 | local1
  30. | frame-0 | old block pointer
  31. | frame+2 | old program counter
  32. C | frame+4 | arg1
  33. D | frame+6 | arg2
  34. E | frame+8 | arg3
  35. F | frame+10 | arg4
  36.  
  37. .--------------------------------------------------------------------
  38. | 16-bit instructions
  39. '--------------------------------------------------------------------
  40. 0x : lda fast : A = <fast>
  41. 1x : ldb fast : B = <fast>
  42. 2x : push fast : push <fast> to the stack
  43. 3x : sta fast : <fast> = A
  44. 4x : lda #x : A = #x
  45. 5x : ldb #x : B = #x
  46. 6x : push #x : push #x to the stack
  47. 7x : add #x : A += #x
  48. 80 xx : lda near : A = <near>
  49. 81 xx xx : lda far : A = <far>
  50. 82 xx : ldb near : B = <near>
  51. 83 xx xx : ldb far : B = <far>
  52. 84 xx : push near : push <near> to the stack
  53. 85 xx xx : push far : push <far> to the stack
  54. 86 xx : sta near : <near> = A
  55. 87 xx xx : sta far : <far> = A
  56. 88 xx : lda #xx : A = #xx (sign extend)
  57. 89 xx xx : lda #xxxx : A = #xxxx
  58. 8A xx : ldb #xx : B = #xx (sign extend)
  59. 8B xx xx : ldb #xxxx : B = #xxxx
  60. 8C xx : push #xx : push #xx to the stack
  61. 8D xx xx : push #xxxx : push #xxxx to the stack
  62. 8E xx : add #xx : A += #xx (sign extend)
  63. 8F xx xx : add #xxxx : A += #xxxx
  64.  
  65. 00-3f and 40-7f share logic except for sta/add
  66. 00-7f and 80-8f share logic
  67.  
  68. 90 xx xx : lda xxxx : A = <abs>
  69. 91 xx xx : ldb xxxx : B = <abs>
  70. 92 xx xx : push xxxx : push <abs> to the stack
  71. 93 xx xx : sta xxxx : <abs> = A
  72.  
  73. 94 xx xx : blda xxxx : A = <byte abs>
  74. 95 xx xx : bldb xxxx : B = <byte abs>
  75. 96 xx xx : bpush xxxx : push <byte abs> to the stack (zero extended)
  76. 97 xx xx : bsta xxxx : <byte abs> = A
  77.  
  78. 98 xx xx : blda far : A = <byte far>
  79. 99 xx xx : bldb far : B = <byte far>
  80. 9A xx xx : bpush far : push <byte far> to the stack
  81. 9B xx xx : bsta far : <byte far> = A
  82.  
  83. 9C xx xx : leaa far : A = &<far>
  84. 9D xx xx : leab far : B = &<far>
  85. 9E xx xx : pea far : push &<far> to the stack
  86. 9F xx xx : ?? far : reserved
  87.  
  88. A0 : deref : A = *A
  89. A1 : popstore : pop B, *B = A
  90. A2 : bderef : A = (byte)*A
  91. A3 : bpopstore : pop B, (byte)*B = A
  92. A4 : pha : push A to the stack
  93. A5 : plb : pop B from the stack
  94. A6 xx : unstack #xx : sp += #xx (for cleaning up after a function)
  95. A7 xx xx : unstack #xxxx : sp += #xxxx
  96. A8 xx xx : call xxxx : call an address (push PC, PC = xxxx, push FP, FP = SP)
  97. A9 : callptr : call A
  98. AA xxxxyy: call xxxx, #yy : call an address, decrease the stack pointer by yy
  99. AB yy : callptr #yy : call A, decrease the stack pointer by yy
  100. AC : : operand size override prefix
  101. AD : : address size override prefix
  102. AE : return : return (SP = FP, pop FP, pop PC)
  103. AF : swap : A = B and B = A
  104.  
  105. B0 : ucmplt : A = A < B (unsigned)
  106. B1 : ucmple : A = A <= B (unsigned)
  107. B2 : ucmpgt : A = A > B (unsigned)
  108. B3 : ucmpge : A = A >= B (unsigned)
  109. B4 : scmplt : A = A < B (signed)
  110. B5 : scmple : A = A <= B (signed)
  111. B6 : scmpgt : A = A > B (signed)
  112. B7 : scmpge : A = A >= B (signed)
  113. B8 : cmpeq : A = A == B
  114. B9 : cmpne : A = A != B
  115. BA : not : A = !A (or == 0)
  116. BB : neg : A = -A
  117. BC : compl : A = ~A
  118. BD : and : A = A & B
  119. BE : or : A = A | B
  120. BF : xor : A = A ^ B
  121. B0-B7 share logic
  122. entire block sets A
  123.  
  124. C0 : add : A += B
  125. C1 : dec : A--
  126. C2 : rsub : A = B-A
  127. C3 : sub : A -= B
  128. C4 : lshift : A <<= B (unsigned)
  129. C5 : double : A <<= 1
  130. C6 : rshift : A >>= B (unsigned)
  131. C7 : arshift : A >>= B (signed)
  132. C8 : divu : A /= B (unsigned)
  133. C9 : divs : A /= B (signed)
  134. CA : modu : A %= B (unsigned)
  135. CB : mods : A %= B (signed)
  136. CC : mult : A *= B
  137. CD xy : sloadbf x,y : signed bit extract. a = b>>x, only keeping y bits (sign extended)
  138. CE xy : uloadbf x,y : unsigned bit extract. a = b>>x, only keeping y bits
  139. CF xy : storebf x,y : bit insert. a = (b&mask)|(a<<x)
  140. C0-C3 are all addition/subtraction
  141. C4-C7 are all shifting
  142. signed and unsigned opcodes share logic
  143. entire block sets A
  144.  
  145. D0 xx : jumpt xx : PC += xx + 1 IF A==1
  146. D1 xx : jumpt xx : PC -= xx - 1 IF A==1
  147. D2 xx xx : jumpt xxxx : PC = <abs> IF A==1
  148. D3 xxyyzz: jumpt xxxxxx : PC = <long> IF A==1
  149. D4 xx : jumpf xx : PC += xx + 1 IF A==0
  150. D5 xx : jumpf xx : PC -= xx - 1 IF A==0
  151. D6 xx xx : jumpf xxxx : PC = <abs> IF A==0
  152. D7 xxyyzz: jumpf xxxxxx : PC = <long> IF A==0
  153.  
  154. D8 xx : jump xx : PC += xx + 1
  155. D9 xx : jump xx : PC -= xx - 1
  156. DA xx xx : jump xxxx : PC = <abs>
  157. DB xxyyzz: jump xxxxxx : PC = <long>
  158. DC ?? : switchrange : switch statement with a range
  159. DD ?? : switchlist : switch statement with a list of values
  160. DE xx : in xx : input on port x (A = read value)
  161. DF xx : out xx : output on port x (write A to port)
  162.  
  163. E0 : extenda : sign extend A from 8 bits to 16
  164. E1 : extendb : sign extend B from 8 bits to 16
  165. E0 xx xx : copy #xxxx : memcpy(b, a, #xxxx)
  166. E1 xx xx : mcmp #xxxx : memcmp(b, a, #xxxx)
  167. E2 xx xx : fill #xxxx : memset(b, a, #xxxx) ? maybe it'd be better as memcpy without changing b
  168. E3 xx xx : :
  169. E4 xx xx : :
  170. E5 xx xx : :
  171. E6 xx xx : :
  172. E7 xx xx : :
  173. E8 xx xx : :
  174. E9 xx xx : :
  175. EA xx xx : :
  176. EB xx xx : :
  177. EC : lda sp : A = sp
  178. ED : sta sp : sp = A
  179. EE xx : zalloc #xx : decrease stack pointer by a constant and fill newly allocated bytes with zeros
  180. EF xx : direct count : directly increase/decrease a variable
  181.  
  182. direct count instruction takes a parameter:
  183. LLmm ffff
  184. |||| ++++- "Fast" stack reference, 12 local variables or 4 arguments
  185. ||++------ amount. index into 1, 2, -1, -2
  186. ++-------- 0 no special effect
  187. 1 load A with the new count value
  188. 2 use old count value as a pointer and load A with it. (increase by 1 means zero extended byte, 2 means word)
  189. 3 use old count value as a pointer and load it with A. (increase by 1 means byte, 2 means word)
  190. mnemonics:
  191. count var, 1 : directly count a variable up/down
  192. ldcount var, 1 : directly count a variable up/down and load the new value into A
  193. plcount var, 1 : directly count a variable up/down and use the old value as a pointer to load
  194. pscount var, 1 : directly count a variable up/down and use the old value as a pointer to store
  195.  
  196. .--------------------------------------------------------------------
  197. | 32-bit instructions (operand size override)
  198. '--------------------------------------------------------------------
  199. AC 0x : lda32 fast : A = <fast>
  200. AC 1x : ldb32 fast : B = <fast>
  201. AC 2x : push32 fast : push <fast> to the stack
  202. AC 3x : sta32 fast : <fast> = A
  203.  
  204. AC 80 xx : lda32 near : A = <near>
  205. AC 81 xx xx : lda32 far : A = <far>
  206. AC 82 xx : ldb32 near : B = <near>
  207. AC 83 xx xx : ldb32 far : B = <far>
  208. AC 84 xx : push32 near : push <near> to the stack
  209. AC 85 xx xx : push32 far : push <far> to the stack
  210. AC 86 xx : sta32 near : <near> = A
  211. AC 87 xxxxxxxx : sta32 far : <far> = A
  212. AC 89 xxxxxxxx : lda32 #xxxxxxxx : A = #xxxxxxxx
  213. AC 8B xxxxxxxx : ldb32 #xxxxxxxx : B = #xxxxxxxx
  214. AC 8D xxxxxxxx : push32 #xxxxxxxx : push #xxxxxxxx to the stack
  215. AC 8F xxxxxxxx : add32 #xxxxxxxx : A += #xxxxxxxx
  216.  
  217. AC 90 xx xx : lda32 xxxx : A = <abs>
  218. AC 91 xx xx : ldb32 xxxx : B = <abs>
  219. AC 92 xx xx : push32 xxxx : push <abs> to the stack
  220. AC 93 xx xx : sta32 xxxx : <abs> = A
  221.  
  222. AC A0 : deref32 : A = *A
  223. AC A1 : popstore32 : pop B, *B = A
  224.  
  225. AC A4 : pha32 : push A to the stack
  226. AC A5 : plb32 : pop B from the stack
  227.  
  228. AC B0 : ucmplt32 : A = A < B (unsigned)
  229. AC B1 : ucmple32 : A = A <= B (unsigned)
  230. AC B2 : ucmpgt32 : A = A > B (unsigned)
  231. AC B3 : ucmpge32 : A = A >= B (unsigned)
  232. AC B4 : scmplt32 : A = A < B (signed)
  233. AC B5 : scmple32 : A = A <= B (signed)
  234. AC B6 : scmpgt32 : A = A > B (signed)
  235. AC B7 : scmpge32 : A = A >= B (signed)
  236. AC B8 : cmpeq32 : A = A == B
  237. AC B9 : cmpne32 : A = A != B
  238. AC BA : not32 : A = !A (or == 0)
  239.  
  240. AC C6 : rshift32 : A >>= B (unsigned)
  241. AC C7 : arshift32 : A >>= B (signed)
  242. AC C8 : divu32 : A /= B (unsigned)
  243. AC C9 : divs32 : A /= B (signed)
  244. AC CA : modu32 : A %= B (unsigned)
  245. AC CB : mods32 : A %= B (signed)
  246.  
  247. AC E0 : extenda32 : sign extend A from 16 bits to 32
  248. AC E1 : extendb32 : sign extend B from 16 bits to 32
  249.  
  250. .--------------------------------------------------------------------
  251. | Address size override (maybe 24-bit or 32-bit)
  252. '--------------------------------------------------------------------
  253. AD 90 xxxxxxxx : lda xxxxxxxx : A = <abs>
  254. AD 91 xxxxxxxx : ldb xxxxxxxx : B = <abs>
  255. AD 92 xxxxxxxx : push xxxxxxxx : push <abs> to the stack
  256. AD 93 xxxxxxxx : sta xxxxxxxx : <abs> = A
  257.  
  258. AD 94 xxxxxxxx : blda xxxxxxxx : A = <byte abs>
  259. AD 95 xxxxxxxx : bldb xxxxxxxx : B = <byte abs>
  260. AD 96 xxxxxxxx : bpush xxxxxxxx : push <byte abs> to the stack (zero extended)
  261. AD 97 xxxxxxxx : bsta xxxxxxxx : <byte abs> = A
  262.  
  263. AD A0 : deref : A = *A
  264. AD A1 : popstore : pop B, *B = A
  265. AD A2 : bderef : A = (byte)*A
  266. AD A3 : bpopstore : pop B, (byte)*B = A
  267.  
  268. .--------------------------------------------------------------------
  269. | Operand and address size override
  270. '--------------------------------------------------------------------
  271. AC AD 90 xxxxxxxx : lda32 xxxxxxxx : A = <abs>
  272. AC AD 91 xxxxxxxx : ldb32 xxxxxxxx : B = <abs>
  273. AC AD 92 xxxxxxxx : push32 xxxxxxxx : push <abs> to the stack
  274. AC AD 93 xxxxxxxx : sta32 xxxxxxxx : <abs> = A
  275.  
  276. AC AD A0 : deref32 : A = *A
  277. AC AD A1 : popstore32 : pop B, *B = A
  278.  
  279. .--------------------------------------------------------------------
  280. | Code examples
  281. '--------------------------------------------------------------------
  282. -switch statements-
  283. switchrange
  284. .word 1, 5 ; range is 1 to 5
  285. .word default ; for if outside 1 to 5
  286. .word was1
  287. .word was2
  288. .word was3
  289. .word was4
  290. .word was5
  291.  
  292. switchlist
  293. .word 5 ; 5 cases
  294. .word 1, was1
  295. .word 2, was2
  296. .word 3, was3
  297. .word 4, was4
  298. .word 5, was5
  299. .word default
  300.  
  301. -array reading-
  302. lda index
  303. add #array_address
  304. deref
  305.  
  306. -array writing-
  307. lda index
  308. add #array_address
  309. pha
  310. lda (whatever value to write)
  311. popstore
  312.  
  313. -loop-
  314. lda #0
  315. sta index
  316. loop:
  317. ; get place to write
  318. lda #array
  319. ldb index
  320. add
  321. pha
  322.  
  323. ; get index*index
  324. lda index
  325. ldb index
  326. mulu
  327. popstore
  328.  
  329. lda index
  330. ldb #10
  331. cmpne
  332. jumpt loop
  333.  
  334.  
  335. -loop2-
  336. lda #0
  337. sta counter
  338. sta sum
  339. loop:
  340. count sum, 1
  341. ldcount counter, -1
  342. jumpt, loop
  343. return
  344.  
  345.  
  346. -strlen-
  347. lda #0
  348. sta length
  349. loop:
  350. lda arg1
  351. bderef
  352. jumpf exit
  353. lda length
  354. add #1
  355. sta length
  356.  
  357. lda arg1
  358. add #1
  359. sta arg1
  360. jump loop
  361. exit:
  362. lda length
  363. return
  364.  
  365. -strlen with count-
  366. lda #0
  367. sta length
  368. loop:
  369. plcount arg1, 1
  370. jumpf exit
  371. count length, 1
  372. jump loop
  373. exit:
  374. lda length
  375. return
  376.  
  377.  
  378. -utf8 strlen-
  379. zalloc #2 ; init length
  380. loop:
  381. plcount arg1, 1 ; a = *(arg1++)
  382. jumpf exit ; stop if it's zero (end of string)
  383.  
  384. ldb #$80 ; characters < $80 are ASCII,
  385. ucmplt ; so they increase the counter
  386. jumpt yes
  387.  
  388. ldb #$bf ; characters > $bf are starting characters
  389. ucmplt ; so they also increase the counter
  390. jumpf loop
  391.  
  392. yes:
  393. count length, 1 ; length++
  394. jump loop
  395.  
  396. exit:
  397. lda length ; return with length in A
  398. return
  399.  
  400.  
  401.  
  402.  
  403. -calling functions-
  404. push #1
  405. push #2
  406. push #3
  407. push #4
  408. call sum
  409. unstack #4*2
  410.  
  411. sum:
  412. lda arg1
  413. ldb arg2
  414. add
  415. ldb arg3
  416. add
  417. ldb arg4
  418. add
  419. return
  420.  
  421. -passing -
  422. pea variable
  423. call function
  424. unstack #1*2
  425.  
  426. function: ; writes 1 to the passed argument
  427. push arg1
  428. lda #1
  429. popstore
  430. return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement