Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

382 Zeilen
8.1KB

  1. ; E06-S05: interface method call fixture in x128.
  2. ;
  3. ; Runs under CR=$0E on the E06-S01 value ABI, the E06-S02 trampoline, the
  4. ; E06-S03 table shape, and the E06-S04 conversion API. It checks:
  5. ; - two classes dispatch the same interface slot to different methods, and
  6. ; self is the underlying object ($1111 / $2222), not the value record;
  7. ; - one class dispatches through two of its interface tables, so the same
  8. ; object reaches different methods by table pointer alone;
  9. ; - a callee can itself make an interface call and pass on a one-byte result;
  10. ; - a byte argument and a two-byte argument arrive at FP+2..FP+4, a two-byte
  11. ; result comes back in A/X, and the caller's frame stack is restored.
  12. ;
  13. ; The slots are the compile-time interface slots (resolved by the compiler's
  14. ; iface_slot in the table fixture); the table pointer is read at run time from
  15. ; the value, which is what lets one call site reach two classes.
  16. ;
  17. ; MB_DATA flags 0..3 report the four phases.
  18. .setcpu "6502"
  19. .include "../../src/common/c128.inc"
  20. .include "../../src/common/mailbox.inc"
  21. .include "../../src/common/print.inc"
  22. .include "../../src/common/frames.inc"
  23. .include "../../src/common/interfaces.inc"
  24. .import pr_char, pr_cr, pr_text
  25. .import frame_init, frame_enter, frame_leave, frame_push_byte, frame_push_word, frame_discard
  26. .import if_call, if_error
  27. .macro TEXT src, len
  28. lda #<src
  29. ldx #>src
  30. ldy #len
  31. jsr pr_text
  32. .endmacro
  33. .macro PHASE n
  34. lda #n
  35. sta MB_CODE
  36. lda #$00
  37. sta MB_CODE+1
  38. .endmacro
  39. .macro FAIL_CS
  40. bcc :+
  41. jmp @fail
  42. :
  43. .endmacro
  44. .macro FAIL_NE
  45. beq :+
  46. jmp @fail
  47. :
  48. .endmacro
  49. ; A/X = self. A method whose self is not its class's object counts the miss
  50. ; and returns failure instead of reporting a result.
  51. .macro SELF_IS lo, hi
  52. cmp #lo
  53. bne @selfbad
  54. cpx #hi
  55. beq @selfok
  56. @selfbad:
  57. inc self_bad
  58. lda #$00
  59. ldx #$00
  60. rts
  61. @selfok:
  62. .endmacro
  63. .segment "LOADADDR"
  64. .word $1C01
  65. .segment "EXEHDR"
  66. .word basic_end
  67. .word 10
  68. .byte $9E
  69. .byte "7181"
  70. .byte $00
  71. basic_end:
  72. .word $0000
  73. .segment "MAILBOX"
  74. .res MB_SIZE
  75. .segment "STARTUP"
  76. .export test_entry, test_end
  77. test_entry:
  78. php
  79. sei
  80. ldx #MB_SIZE - 1
  81. lda #$00
  82. @clr: sta MB_BASE,x
  83. dex
  84. bpl @clr
  85. lda #MB_MAGIC0_VALUE
  86. sta MB_MAGIC0
  87. lda #MB_MAGIC1_VALUE
  88. sta MB_MAGIC1
  89. lda #MB_PROD_PROGRAM
  90. sta MB_PRODUCER
  91. lda #MB_ST_RUNNING
  92. sta MB_STATUS
  93. lda #$00
  94. sta MB_CODE
  95. sta MB_CODE+1
  96. sta self_bad
  97. sta a_calls
  98. sta b_calls
  99. sta leaf_calls
  100. ldx #$03
  101. @flags: sta MB_DATA,x
  102. dex
  103. bpl @flags
  104. lda MMU_CR
  105. sta saved_cr
  106. lda #CR_RAM0_KERNAL
  107. sta MMU_CR
  108. lda #PR_CLEAR
  109. jsr pr_char
  110. TEXT title, title_len
  111. jsr pr_cr
  112. ; 1: one call site, two classes, two methods.
  113. PHASE 1
  114. lda #<val_a_foo
  115. ldx #>val_a_foo
  116. ldy #0
  117. jsr if_call
  118. sta result_a
  119. lda if_error
  120. FAIL_NE
  121. lda result_a
  122. cmp #$A0
  123. FAIL_NE
  124. lda a_calls
  125. cmp #1
  126. FAIL_NE
  127. lda #<val_b_foo
  128. ldx #>val_b_foo
  129. ldy #0
  130. jsr if_call
  131. sta result_a
  132. lda if_error
  133. FAIL_NE
  134. lda result_a
  135. cmp #$B0
  136. FAIL_NE
  137. lda b_calls
  138. cmp #1
  139. FAIL_NE
  140. lda self_bad
  141. FAIL_NE
  142. lda #$01
  143. sta MB_DATA+0
  144. ; 2: one class, two interface tables, different methods.
  145. PHASE 2
  146. lda #<val_a_bar
  147. ldx #>val_a_bar
  148. ldy #0
  149. jsr if_call
  150. sta result_a
  151. lda if_error
  152. FAIL_NE
  153. lda result_a
  154. cmp #$C0
  155. FAIL_NE
  156. lda a_calls
  157. cmp #2
  158. FAIL_NE
  159. lda self_bad
  160. FAIL_NE
  161. lda #$01
  162. sta MB_DATA+1
  163. ; 3: an interface call inside a method, one-byte result passed on.
  164. PHASE 3
  165. lda #<val_a_foo
  166. ldx #>val_a_foo
  167. ldy #1
  168. jsr if_call
  169. sta result_a
  170. lda if_error
  171. FAIL_NE
  172. lda result_a
  173. cmp #$5B
  174. FAIL_NE
  175. lda a_calls
  176. cmp #3
  177. FAIL_NE
  178. lda leaf_calls
  179. cmp #1
  180. FAIL_NE
  181. lda self_bad
  182. FAIL_NE
  183. lda #$01
  184. sta MB_DATA+2
  185. ; 4: arguments and a two-byte result through an interface call.
  186. PHASE 4
  187. jsr frame_init
  188. lda #$34
  189. ldx #$12
  190. jsr frame_push_word ; arg1 = $1234
  191. FAIL_CS
  192. lda #$07
  193. jsr frame_push_byte ; arg0 = 7
  194. FAIL_CS
  195. lda #<val_a_foo
  196. ldx #>val_a_foo
  197. ldy #2
  198. jsr if_call
  199. sta result_a
  200. stx result_x
  201. lda if_error
  202. FAIL_NE
  203. lda #$03
  204. ldx #$00
  205. jsr frame_discard
  206. lda result_a
  207. cmp #$3B ; $1234 + 7
  208. FAIL_NE
  209. lda result_x
  210. cmp #$12
  211. FAIL_NE
  212. lda FRAME_SP
  213. cmp #<FRAME_STACK_TOP
  214. FAIL_NE
  215. lda FRAME_SP+1
  216. cmp #>FRAME_STACK_TOP
  217. FAIL_NE
  218. lda a_calls
  219. cmp #4
  220. FAIL_NE
  221. lda self_bad
  222. FAIL_NE
  223. lda #$01
  224. sta MB_DATA+3
  225. TEXT ok_msg, ok_len
  226. jsr pr_cr
  227. lda #MB_ST_PASS
  228. sta MB_STATUS
  229. lda #$00
  230. sta MB_CODE
  231. sta MB_CODE+1
  232. jmp @restore
  233. @fail:
  234. lda #MB_ST_FAIL
  235. sta MB_STATUS
  236. TEXT fail_msg, fail_len
  237. jsr pr_cr
  238. @restore:
  239. lda saved_cr
  240. sta MMU_CR
  241. plp
  242. rts
  243. .segment "CODE"
  244. ; IFOO slot 0 of class A: byte result, self checked.
  245. m_a0:
  246. SELF_IS $11, $11
  247. inc a_calls
  248. lda #$A0
  249. ldx #$00
  250. rts
  251. ; IFOO slot 1 of class A: calls leaf through val_leaf and adds one.
  252. m_a1:
  253. SELF_IS $11, $11
  254. inc a_calls
  255. lda #<val_leaf
  256. ldx #>val_leaf
  257. ldy #$00
  258. jsr if_call
  259. sta child
  260. stx child_x
  261. lda if_error
  262. bne @bad
  263. lda child
  264. clc
  265. adc #$01
  266. ldx #$00
  267. rts
  268. @bad: inc self_bad
  269. lda #$00
  270. ldx #$00
  271. rts
  272. ; IFOO slot 2 of class A: (byte, word) -> word sum.
  273. m_addw:
  274. SELF_IS $11, $11
  275. inc a_calls
  276. lda #$00
  277. ldx #$00
  278. jsr frame_enter
  279. bcs @bad
  280. ldy #$02
  281. lda (FRAME_FP),y
  282. sta tmp
  283. iny
  284. lda (FRAME_FP),y
  285. clc
  286. adc tmp
  287. sta res_lo
  288. iny
  289. lda (FRAME_FP),y
  290. adc #$00
  291. sta res_hi
  292. jsr frame_leave
  293. lda res_lo
  294. ldx res_hi
  295. clc
  296. rts
  297. @bad: lda #$00
  298. ldx #$00
  299. sec
  300. rts
  301. ; IBAR slot 0 of class A: a different method for the same object.
  302. m_abar:
  303. SELF_IS $11, $11
  304. inc a_calls
  305. lda #$C0
  306. ldx #$00
  307. rts
  308. ; IFOO slot 0 of class B.
  309. m_b0:
  310. SELF_IS $22, $22
  311. inc b_calls
  312. lda #$B0
  313. ldx #$00
  314. rts
  315. ; Target of the nested call.
  316. m_leaf:
  317. inc leaf_calls
  318. lda #$5A
  319. ldx #$00
  320. rts
  321. .segment "DATA"
  322. ; Object pointers are only identities here; the methods compare them.
  323. val_a_foo: .word $1111, tab_a_foo
  324. val_a_bar: .word $1111, tab_a_bar
  325. val_b_foo: .word $2222, tab_b_foo
  326. val_leaf: .word $9999, tab_leaf
  327. tab_a_foo: .word m_a0, m_a1, m_addw
  328. tab_a_bar: .word m_abar
  329. tab_b_foo: .word m_b0
  330. tab_leaf: .word m_leaf
  331. .assert tab_a_bar - tab_a_foo = 3 * IF_SLOT_SIZE, error, "IFOO table size"
  332. .assert tab_b_foo - tab_a_bar = 1 * IF_SLOT_SIZE, error, "IBAR table size"
  333. .segment "RODATA"
  334. title: .byte "NOVA128 IFCALL TEST"
  335. title_len = * - title
  336. ok_msg: .byte "IFCALL OK"
  337. ok_len = * - ok_msg
  338. fail_msg: .byte "IFCALL FAIL"
  339. fail_len = * - fail_msg
  340. .segment "BSS"
  341. saved_cr: .res 1
  342. a_calls: .res 1
  343. b_calls: .res 1
  344. leaf_calls: .res 1
  345. self_bad: .res 1
  346. result_a: .res 1
  347. result_x: .res 1
  348. child: .res 1
  349. child_x: .res 1
  350. tmp: .res 1
  351. res_lo: .res 1
  352. res_hi: .res 1
  353. test_end:

Powered by TurnKey Linux.