Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

532 řádky
11KB

  1. ; E06-S04: concrete-to-interface conversion fixture in x128.
  2. ;
  3. ; Runs under CR=$0E on the E06-S01 value ABI, the E06-S02 dispatch core, and
  4. ; the E06-S03 table shape. It checks:
  5. ; - assigning a class reference to an interface value writes the object
  6. ; pointer and the interface's method table (if_assign mode 1);
  7. ; - a null object converts to the canonical four zero bytes;
  8. ; - interface-to-interface assignment copies all four bytes verbatim, and a
  9. ; zero source pointer is IF_ERR_NULL;
  10. ; - a four-byte field and array elements at IF_VALUE_SIZE stride keep the
  11. ; pair, and an element address that wraps is IF_ERR_RANGE;
  12. ; - pushing an interface value as an argument leaves the object low byte at
  13. ; FP+2 and restores the frame stack;
  14. ; - a converted value survives the four-byte result area.
  15. ;
  16. ; The tables below are the shape E06-S03 emits: two-byte method addresses in
  17. ; interface slot order, no header. MB_DATA flags 0..5 report the six 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_discard
  26. .import if_assign, if_arg_push, if_elem_store, if_elem_load
  27. .import if_is_null, if_ret_store, if_ret_load
  28. .import if_error
  29. .importzp if_obj, if_tab, if_dst, if_src
  30. .macro TEXT src, len
  31. lda #<src
  32. ldx #>src
  33. ldy #len
  34. jsr pr_text
  35. .endmacro
  36. .macro PHASE n
  37. lda #n
  38. sta MB_CODE
  39. lda #$00
  40. sta MB_CODE+1
  41. .endmacro
  42. .macro POINT var
  43. lda #<var
  44. sta tptr
  45. lda #>var
  46. sta tptr+1
  47. .endmacro
  48. .macro SETDST var
  49. lda #<var
  50. sta if_dst
  51. lda #>var
  52. sta if_dst+1
  53. .endmacro
  54. .macro SETSRC var
  55. lda #<var
  56. sta if_src
  57. lda #>var
  58. sta if_src+1
  59. .endmacro
  60. .macro OBJECT var
  61. lda #<var
  62. sta if_obj
  63. lda #>var
  64. sta if_obj+1
  65. .endmacro
  66. .macro TABLE var
  67. lda #<var
  68. sta if_tab
  69. lda #>var
  70. sta if_tab+1
  71. .endmacro
  72. .macro EXPECT v0, v1, v2, v3
  73. lda #v0
  74. sta e0
  75. lda #v1
  76. sta e1
  77. lda #v2
  78. sta e2
  79. lda #v3
  80. sta e3
  81. .endmacro
  82. .macro FAIL_CS
  83. bcc :+
  84. jmp @fail
  85. :
  86. .endmacro
  87. .macro FAIL_CC
  88. bcs :+
  89. jmp @fail
  90. :
  91. .endmacro
  92. .macro FAIL_NE
  93. beq :+
  94. jmp @fail
  95. :
  96. .endmacro
  97. .macro CHK addr, val
  98. lda addr
  99. cmp #val
  100. beq :+
  101. pha
  102. lda #<addr
  103. sta MB_ADDR
  104. lda #>addr
  105. sta MB_ADDR+1
  106. pla
  107. sta MB_CODE
  108. lda #$00
  109. sta MB_CODE+1
  110. jmp @fail
  111. :
  112. .endmacro
  113. .segment "LOADADDR"
  114. .word $1C01
  115. .segment "EXEHDR"
  116. .word basic_end
  117. .word 10
  118. .byte $9E
  119. .byte "7181"
  120. .byte $00
  121. basic_end:
  122. .word $0000
  123. .segment "MAILBOX"
  124. .res MB_SIZE
  125. .segment "ZEROPAGE"
  126. tptr: .res 2
  127. .segment "STARTUP"
  128. .export test_entry, test_end
  129. test_entry:
  130. php
  131. sei
  132. ldx #MB_SIZE - 1
  133. lda #$00
  134. @clr: sta MB_BASE,x
  135. dex
  136. bpl @clr
  137. lda #MB_MAGIC0_VALUE
  138. sta MB_MAGIC0
  139. lda #MB_MAGIC1_VALUE
  140. sta MB_MAGIC1
  141. lda #MB_PROD_PROGRAM
  142. sta MB_PRODUCER
  143. lda #MB_ST_RUNNING
  144. sta MB_STATUS
  145. lda #$00
  146. sta MB_CODE
  147. sta MB_CODE+1
  148. sta MB_ADDR
  149. sta MB_ADDR+1
  150. sta fail_mask
  151. ldx #$05
  152. lda #$00
  153. @flags: sta MB_DATA,x
  154. dex
  155. bpl @flags
  156. lda #$5A
  157. sta holder
  158. sta holder+1
  159. lda MMU_CR
  160. sta saved_cr
  161. lda #CR_RAM0_KERNAL
  162. sta MMU_CR
  163. lda #PR_CLEAR
  164. jsr pr_char
  165. TEXT title, title_len
  166. jsr pr_cr
  167. ; 1: a class reference assigns the object/table pair.
  168. PHASE 1
  169. OBJECT obj_a_stub
  170. TABLE tab_a
  171. lda #<val_a
  172. ldx #>val_a
  173. ldy #1
  174. jsr if_assign
  175. FAIL_CS
  176. CHK if_error, IF_OK
  177. EXPECT <obj_a_stub, >obj_a_stub, <tab_a, >tab_a
  178. POINT val_a
  179. jsr cmp_val
  180. FAIL_CS
  181. lda #$01
  182. sta MB_DATA+0
  183. ; 2: null converts to the canonical four zero bytes.
  184. PHASE 2
  185. lda #$00
  186. sta if_obj
  187. sta if_obj+1
  188. TABLE tab_a
  189. lda #<val_b
  190. ldx #>val_b
  191. ldy #1
  192. jsr if_assign
  193. FAIL_CS
  194. CHK if_error, IF_OK
  195. EXPECT $00, $00, $00, $00
  196. POINT val_b
  197. jsr cmp_val
  198. FAIL_CS
  199. lda #<val_b
  200. ldx #>val_b
  201. jsr if_is_null
  202. FAIL_CC
  203. ; A null value assigned verbatim stays canonical.
  204. SETSRC val_b
  205. lda #<val_c
  206. ldx #>val_c
  207. ldy #0
  208. jsr if_assign
  209. FAIL_CS
  210. POINT val_c
  211. jsr cmp_val
  212. FAIL_CS
  213. lda #$01
  214. sta MB_DATA+1
  215. ; 3: interface-to-interface assignment preserves all four bytes.
  216. PHASE 3
  217. SETSRC val_a
  218. lda #<val_d
  219. ldx #>val_d
  220. ldy #0
  221. jsr if_assign
  222. FAIL_CS
  223. EXPECT <obj_a_stub, >obj_a_stub, <tab_a, >tab_a
  224. POINT val_d
  225. jsr cmp_val
  226. FAIL_CS
  227. lda #$00
  228. sta if_src
  229. sta if_src+1
  230. lda #<val_d
  231. ldx #>val_d
  232. ldy #0
  233. jsr if_assign
  234. FAIL_CC
  235. CHK if_error, IF_ERR_NULL
  236. POINT val_d
  237. jsr cmp_val
  238. FAIL_CS
  239. lda #$01
  240. sta MB_DATA+2
  241. ; 4: one field and three array elements keep their own values.
  242. PHASE 4
  243. SETSRC val_a
  244. lda #<holder_iface
  245. ldx #>holder_iface
  246. ldy #0
  247. jsr if_assign
  248. FAIL_CS
  249. POINT holder_iface
  250. jsr cmp_val
  251. FAIL_CS
  252. CHK holder, $5A
  253. CHK holder+1, $5A
  254. SETSRC val_a
  255. lda #<elems
  256. ldx #>elems
  257. ldy #0
  258. jsr if_elem_store
  259. FAIL_CS
  260. lda #<elems
  261. ldx #>elems
  262. ldy #2
  263. jsr if_elem_store
  264. FAIL_CS
  265. SETSRC val_b
  266. lda #<elems
  267. ldx #>elems
  268. ldy #1
  269. jsr if_elem_store
  270. FAIL_CS
  271. SETDST val_e
  272. lda #<elems
  273. ldx #>elems
  274. ldy #2
  275. jsr if_elem_load
  276. FAIL_CS
  277. EXPECT <obj_a_stub, >obj_a_stub, <tab_a, >tab_a
  278. POINT val_e
  279. jsr cmp_val
  280. FAIL_CS
  281. SETDST val_f
  282. lda #<elems
  283. ldx #>elems
  284. ldy #1
  285. jsr if_elem_load
  286. FAIL_CS
  287. EXPECT $00, $00, $00, $00
  288. POINT val_f
  289. jsr cmp_val
  290. FAIL_CS
  291. SETDST val_g
  292. lda #<elems
  293. ldx #>elems
  294. ldy #0
  295. jsr if_elem_load
  296. FAIL_CS
  297. EXPECT <obj_a_stub, >obj_a_stub, <tab_a, >tab_a
  298. POINT val_g
  299. jsr cmp_val
  300. FAIL_CS
  301. ; $FF00 + 4*200 wraps past $FFFF.
  302. SETDST val_g
  303. lda #$00
  304. ldx #$FF
  305. ldy #200
  306. jsr if_elem_load
  307. FAIL_CC
  308. CHK if_error, IF_ERR_RANGE
  309. lda #$01
  310. sta MB_DATA+3
  311. ; 5: an argument push puts the object low byte at FP+2.
  312. PHASE 5
  313. jsr frame_init
  314. lda FRAME_SP
  315. sta saved_sp
  316. lda FRAME_SP+1
  317. sta saved_sp+1
  318. lda #<val_a
  319. ldx #>val_a
  320. jsr if_arg_push
  321. FAIL_CS
  322. jsr take_iface
  323. FAIL_CS
  324. lda #IF_VALUE_SIZE
  325. ldx #$00
  326. jsr frame_discard
  327. lda FRAME_SP
  328. cmp saved_sp
  329. FAIL_NE
  330. lda FRAME_SP+1
  331. cmp saved_sp+1
  332. FAIL_NE
  333. lda #$00
  334. ldx #$00
  335. jsr if_arg_push
  336. FAIL_CC
  337. CHK if_error, IF_ERR_NULL
  338. lda FRAME_SP
  339. cmp saved_sp
  340. FAIL_NE
  341. lda FRAME_SP+1
  342. cmp saved_sp+1
  343. FAIL_NE
  344. lda #$01
  345. sta MB_DATA+4
  346. ; 6: a converted value survives the four-byte result area.
  347. PHASE 6
  348. lda #<val_d
  349. ldx #>val_d
  350. jsr if_ret_store
  351. FAIL_CS
  352. lda #<val_c
  353. ldx #>val_c
  354. jsr if_ret_load
  355. FAIL_CS
  356. EXPECT <obj_a_stub, >obj_a_stub, <tab_a, >tab_a
  357. POINT val_c
  358. jsr cmp_val
  359. FAIL_CS
  360. OBJECT obj_a_stub
  361. TABLE tab_b
  362. lda #<val_e
  363. ldx #>val_e
  364. ldy #1
  365. jsr if_assign
  366. FAIL_CS
  367. lda #<val_e
  368. ldx #>val_e
  369. jsr if_ret_store
  370. FAIL_CS
  371. lda #<val_g
  372. ldx #>val_g
  373. jsr if_ret_load
  374. FAIL_CS
  375. EXPECT <obj_a_stub, >obj_a_stub, <tab_b, >tab_b
  376. POINT val_g
  377. jsr cmp_val
  378. FAIL_CS
  379. lda #$01
  380. sta MB_DATA+5
  381. TEXT ok_msg, ok_len
  382. jsr pr_cr
  383. lda #MB_ST_PASS
  384. sta MB_STATUS
  385. lda #$00
  386. sta MB_CODE
  387. sta MB_CODE+1
  388. jmp @restore
  389. @fail:
  390. lda #MB_ST_FAIL
  391. sta MB_STATUS
  392. TEXT fail_msg, fail_len
  393. jsr pr_cr
  394. @restore:
  395. lda saved_cr
  396. sta MMU_CR
  397. plp
  398. rts
  399. ; Reads the four argument bytes at FP+2..FP+5: object, then table.
  400. take_iface:
  401. lda #$00
  402. ldx #$00
  403. jsr frame_enter
  404. bcs @bad
  405. ldy #2
  406. lda (FRAME_FP),y
  407. cmp #<obj_a_stub
  408. bne @bad
  409. iny
  410. lda (FRAME_FP),y
  411. cmp #>obj_a_stub
  412. bne @bad
  413. iny
  414. lda (FRAME_FP),y
  415. cmp #<tab_a
  416. bne @bad
  417. iny
  418. lda (FRAME_FP),y
  419. cmp #>tab_a
  420. bne @bad
  421. jsr frame_leave
  422. clc
  423. rts
  424. @bad: sec
  425. rts
  426. ; C=1 when the four bytes at tptr differ from e0..e3.
  427. cmp_val:
  428. ldy #$00
  429. lda (tptr),y
  430. cmp e0
  431. bne @no
  432. iny
  433. lda (tptr),y
  434. cmp e1
  435. bne @no
  436. iny
  437. lda (tptr),y
  438. cmp e2
  439. bne @no
  440. iny
  441. lda (tptr),y
  442. cmp e3
  443. bne @no
  444. clc
  445. rts
  446. @no: sec
  447. rts
  448. .segment "CODE"
  449. ; Method stubs the tables point at, as E06-S03 emits them.
  450. m_alpha_a:
  451. rts
  452. m_beta_a:
  453. rts
  454. m_alpha_b:
  455. rts
  456. m_beta_b:
  457. rts
  458. .segment "DATA"
  459. obj_a_stub: .res 2 ; stands in for an allocated object
  460. tab_a: .word m_alpha_a, m_beta_a
  461. tab_b: .word m_alpha_b, m_beta_b
  462. .assert * - tab_a = 2 * 2 * IF_SLOT_SIZE, error, "table size"
  463. .segment "RODATA"
  464. title: .byte "NOVA128 CONVERT TEST"
  465. title_len = * - title
  466. ok_msg: .byte "CONVERT OK"
  467. ok_len = * - ok_msg
  468. fail_msg: .byte "CONVERT FAIL"
  469. fail_len = * - fail_msg
  470. .segment "BSS"
  471. saved_cr: .res 1
  472. saved_sp: .res 2
  473. e0: .res 1
  474. e1: .res 1
  475. e2: .res 1
  476. e3: .res 1
  477. fail_mask: .res 1
  478. val_a: .res IF_VALUE_SIZE
  479. val_b: .res IF_VALUE_SIZE
  480. val_c: .res IF_VALUE_SIZE
  481. val_d: .res IF_VALUE_SIZE
  482. val_e: .res IF_VALUE_SIZE
  483. val_f: .res IF_VALUE_SIZE
  484. val_g: .res IF_VALUE_SIZE
  485. holder: .res 2
  486. holder_iface: .res IF_VALUE_SIZE
  487. elems: .res 3 * IF_VALUE_SIZE
  488. test_end:

Powered by TurnKey Linux.