選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

420 行
8.4KB

  1. ; E05-S03: construction/deletion fixture in x128.
  2. ;
  3. ; Runs under CR=$0E with a 4K heap at $4000. It checks:
  4. ; - object header and zeroed fields, then init called once with two args;
  5. ; - delete null is a no-op;
  6. ; - delete calls destroy once with self/fields intact and frees the object;
  7. ; - failed allocation does not call init;
  8. ; - a class without a destructor still frees correctly.
  9. ;
  10. ; MB_DATA flags 0..4 report the five phases.
  11. .setcpu "6502"
  12. .include "../../src/common/c128.inc"
  13. .include "../../src/common/mailbox.inc"
  14. .include "../../src/common/print.inc"
  15. .include "../../src/common/heap.inc"
  16. .include "../../src/common/class.inc"
  17. .include "../../src/common/frames.inc"
  18. .import pr_char, pr_cr, pr_text
  19. .import heap_init, heap_alloc, heap_free, heap_free_total, heap_error
  20. .import frame_init, frame_enter, frame_leave, frame_push_byte, frame_push_word, frame_discard
  21. .import obj_class
  22. .import obj_new, obj_delete, obj_init_ptr, obj_error
  23. HEAP_BASE = $4000
  24. HEAP_PAGES = 16
  25. .macro TEXT src, len
  26. lda #<src
  27. ldx #>src
  28. ldy #len
  29. jsr pr_text
  30. .endmacro
  31. .macro PHASE n
  32. lda #n
  33. sta MB_CODE
  34. lda #$00
  35. sta MB_CODE+1
  36. .endmacro
  37. .macro FAIL_CS
  38. bcc :+
  39. jmp @fail
  40. :
  41. .endmacro
  42. .macro FAIL_CC
  43. bcs :+
  44. jmp @fail
  45. :
  46. .endmacro
  47. .macro FAIL_NE
  48. beq :+
  49. jmp @fail
  50. :
  51. .endmacro
  52. .macro FAIL_EQ
  53. bne :+
  54. jmp @fail
  55. :
  56. .endmacro
  57. .segment "LOADADDR"
  58. .word $1C01
  59. .segment "EXEHDR"
  60. .word basic_end
  61. .word 10
  62. .byte $9E
  63. .byte "7181"
  64. .byte $00
  65. basic_end:
  66. .word $0000
  67. .segment "MAILBOX"
  68. .res MB_SIZE
  69. .segment "ZEROPAGE"
  70. tptr: .res 2
  71. .segment "STARTUP"
  72. .export test_entry, test_end
  73. test_entry:
  74. php
  75. sei
  76. ldx #MB_SIZE - 1
  77. lda #$00
  78. @clr: sta MB_BASE,x
  79. dex
  80. bpl @clr
  81. lda #MB_MAGIC0_VALUE
  82. sta MB_MAGIC0
  83. lda #MB_MAGIC1_VALUE
  84. sta MB_MAGIC1
  85. lda #MB_PROD_PROGRAM
  86. sta MB_PRODUCER
  87. lda #MB_ST_RUNNING
  88. sta MB_STATUS
  89. lda #$00
  90. sta MB_CODE
  91. sta MB_CODE+1
  92. lda MMU_CR
  93. sta saved_cr
  94. lda #CR_RAM0_KERNAL
  95. sta MMU_CR
  96. lda #PR_CLEAR
  97. jsr pr_char
  98. TEXT title, 18
  99. jsr pr_cr
  100. PHASE 1
  101. lda #$00
  102. ldx #>HEAP_BASE
  103. ldy #HEAP_PAGES
  104. jsr heap_init
  105. FAIL_CS
  106. jsr frame_init
  107. lda #$00
  108. sta init_count
  109. sta destroy_count
  110. sta init_error
  111. ; Construct Res(value=$1234, tag=$2A).
  112. lda #$2A
  113. jsr frame_push_byte ; right-to-left: tag first
  114. lda #$34
  115. ldx #$12
  116. jsr frame_push_word ; then value
  117. lda #<init_res
  118. sta obj_init_ptr
  119. lda #>init_res
  120. sta obj_init_ptr+1
  121. lda #<desc_res
  122. ldx #>desc_res
  123. jsr obj_new
  124. FAIL_CS
  125. sta new_obj
  126. stx new_obj+1
  127. lda #3
  128. ldx #$00
  129. jsr frame_discard
  130. lda init_error
  131. FAIL_NE
  132. lda init_count
  133. cmp #1
  134. FAIL_NE
  135. lda init_self
  136. cmp new_obj
  137. FAIL_NE
  138. lda init_self+1
  139. cmp new_obj+1
  140. FAIL_NE
  141. lda init_tag
  142. cmp #$2A
  143. FAIL_NE
  144. lda init_word
  145. cmp #$34
  146. FAIL_NE
  147. lda init_word+1
  148. cmp #$12
  149. FAIL_NE
  150. lda init_tag_before
  151. FAIL_NE
  152. lda init_word_before
  153. ora init_word_before+1
  154. FAIL_NE
  155. lda new_obj
  156. ldx new_obj+1
  157. jsr obj_class
  158. FAIL_CS
  159. cmp #<desc_res
  160. FAIL_NE
  161. cpx #>desc_res
  162. FAIL_NE
  163. lda #$01
  164. sta MB_DATA+0
  165. ; delete null must not call destroy.
  166. PHASE 2
  167. lda #$00
  168. ldx #$00
  169. jsr obj_delete
  170. FAIL_CS
  171. lda obj_error
  172. cmp #OBJ_OK
  173. FAIL_NE
  174. lda destroy_count
  175. FAIL_NE
  176. lda #$01
  177. sta MB_DATA+1
  178. ; Deleting the object calls destroy once, with self and fields intact.
  179. PHASE 3
  180. lda new_obj
  181. ldx new_obj+1
  182. jsr obj_delete
  183. FAIL_CS
  184. lda obj_error
  185. cmp #OBJ_OK
  186. FAIL_NE
  187. lda destroy_count
  188. cmp #1
  189. FAIL_NE
  190. lda destroy_self
  191. cmp new_obj
  192. FAIL_NE
  193. lda destroy_self+1
  194. cmp new_obj+1
  195. FAIL_NE
  196. lda destroy_tag
  197. cmp #$2A
  198. FAIL_NE
  199. lda destroy_word
  200. cmp #$34
  201. FAIL_NE
  202. lda destroy_word+1
  203. cmp #$12
  204. FAIL_NE
  205. lda heap_free_total
  206. cmp #$00
  207. FAIL_NE
  208. lda heap_free_total+1
  209. cmp #$10
  210. FAIL_NE
  211. lda #$01
  212. sta MB_DATA+2
  213. ; Allocation failure must not call init.
  214. PHASE 4
  215. lda #<init_res
  216. sta obj_init_ptr
  217. lda #>init_res
  218. sta obj_init_ptr+1
  219. lda #<desc_huge
  220. ldx #>desc_huge
  221. jsr obj_new
  222. FAIL_CC
  223. lda obj_error
  224. cmp #OBJ_ERR_HEAP
  225. FAIL_NE
  226. lda init_count
  227. cmp #1
  228. FAIL_NE
  229. lda #$01
  230. sta MB_DATA+3
  231. ; A class with no destructor still frees its complete object.
  232. PHASE 5
  233. lda #$00
  234. sta obj_init_ptr
  235. sta obj_init_ptr+1
  236. lda #<desc_plain
  237. ldx #>desc_plain
  238. jsr obj_new
  239. FAIL_CS
  240. sta plain_obj
  241. stx plain_obj+1
  242. lda plain_obj
  243. ldx plain_obj+1
  244. jsr obj_delete
  245. FAIL_CS
  246. lda obj_error
  247. cmp #OBJ_OK
  248. FAIL_NE
  249. lda destroy_count
  250. cmp #1
  251. FAIL_NE
  252. lda heap_free_total
  253. cmp #$00
  254. FAIL_NE
  255. lda heap_free_total+1
  256. cmp #$10
  257. FAIL_NE
  258. lda #$01
  259. sta MB_DATA+4
  260. TEXT object_ok, 9
  261. jsr pr_cr
  262. lda #MB_ST_PASS
  263. sta MB_STATUS
  264. lda #$00
  265. sta MB_CODE
  266. sta MB_CODE+1
  267. jmp @restore
  268. @fail:
  269. lda #MB_ST_FAIL
  270. sta MB_STATUS
  271. TEXT object_fail, 11
  272. jsr pr_cr
  273. @restore:
  274. lda saved_cr
  275. sta MMU_CR
  276. plp
  277. rts
  278. ; init(value as word, tag as byte), arguments at FP+2..FP+4.
  279. init_res:
  280. sta init_self
  281. stx init_self+1
  282. lda #$00
  283. ldx #$00
  284. jsr frame_enter
  285. bcc @entered
  286. lda #1
  287. sta init_error
  288. rts
  289. @entered:
  290. ldy #2
  291. lda (FRAME_FP),y
  292. sta init_word
  293. iny
  294. lda (FRAME_FP),y
  295. sta init_word+1
  296. iny
  297. lda (FRAME_FP),y
  298. sta init_tag
  299. lda init_self
  300. sta tptr
  301. lda init_self+1
  302. sta tptr+1
  303. ldy #2
  304. lda (tptr),y
  305. sta init_tag_before
  306. ldy #3
  307. lda (tptr),y
  308. sta init_word_before
  309. iny
  310. lda (tptr),y
  311. sta init_word_before+1
  312. ldy #2
  313. lda init_tag
  314. sta (tptr),y
  315. ldy #3
  316. lda init_word
  317. sta (tptr),y
  318. iny
  319. lda init_word+1
  320. sta (tptr),y
  321. inc init_count
  322. jsr frame_leave
  323. clc
  324. rts
  325. ; No-argument destructor; it records self and the fields left by init.
  326. destroy_res:
  327. sta destroy_self
  328. stx destroy_self+1
  329. inc destroy_count
  330. lda destroy_self
  331. sta tptr
  332. lda destroy_self+1
  333. sta tptr+1
  334. ldy #2
  335. lda (tptr),y
  336. sta destroy_tag
  337. ldy #3
  338. lda (tptr),y
  339. sta destroy_word
  340. iny
  341. lda (tptr),y
  342. sta destroy_word+1
  343. rts
  344. .segment "DATA"
  345. desc_res:
  346. .word 5 ; header + tag + word
  347. .word destroy_res
  348. .byte 0
  349. .word 0
  350. .byte 0
  351. .assert * - desc_res = CLASS_DESC_SIZE, error, "Res descriptor size"
  352. desc_plain:
  353. .word 2 ; header only
  354. .word 0
  355. .byte 0
  356. .word 0
  357. .byte 0
  358. .assert * - desc_plain = CLASS_DESC_SIZE, error, "plain descriptor size"
  359. desc_huge:
  360. .word $FFFF
  361. .word 0
  362. .byte 0
  363. .word 0
  364. .byte 0
  365. .assert * - desc_huge = CLASS_DESC_SIZE, error, "huge descriptor size"
  366. .segment "RODATA"
  367. title: .byte "NOVA128 OBJECT TEST"
  368. object_ok: .byte "OBJECT OK"
  369. object_fail: .byte "OBJECT FAIL"
  370. .segment "BSS"
  371. saved_cr: .res 1
  372. new_obj: .res 2
  373. plain_obj: .res 2
  374. init_count: .res 1
  375. init_error: .res 1
  376. init_self: .res 2
  377. init_word: .res 2
  378. init_tag: .res 1
  379. init_tag_before: .res 1
  380. init_word_before: .res 2
  381. destroy_count: .res 1
  382. destroy_self: .res 2
  383. destroy_tag: .res 1
  384. destroy_word: .res 2
  385. test_end:

Powered by TurnKey Linux.