|
- ; E05-S01: free-list heap fixture in x128.
- ;
- ; Runs under CR=$0E with the heap at $4000-$4FFF (16 pages). All code and BSS
- ; stay below $4000. The fixture checks the allocator and records one flag per
- ; phase in MB_DATA; the final exhaustion check invokes the stable R005 fault
- ; path, so the mailbox intentionally ends FAIL with code 5.
- ;
- ; Expected screen:
- ; NOVA128 HEAP TEST
- ; HEAP OK
- ; RUNTIME FAULT R005
-
- .setcpu "6502"
- .include "../../src/common/c128.inc"
- .include "../../src/common/mailbox.inc"
- .include "../../src/common/print.inc"
- .include "../../src/common/faults.inc"
- .include "../../src/common/heap.inc"
-
- .import pr_char, pr_cr, pr_text
- .import flt_report
- .import heap_init, heap_alloc, heap_free
- .import heap_base, heap_end, heap_free_head, heap_free_total, heap_error
-
- HEAP_TEST_BASE = $4000
- HEAP_TEST_END = $5000
- HEAP_TEST_PAGES = 16
- HEAP_TEST_SIZE = $1000
-
- .macro TEXT src, len
- lda #<src
- ldx #>src
- ldy #len
- jsr pr_text
- .endmacro
-
- .macro PHASE number
- lda #number
- sta MB_CODE
- lda #$00
- sta MB_CODE+1
- .endmacro
-
- .macro FAIL_CS
- bcc :+
- jmp @fail
- :
- .endmacro
-
- .macro FAIL_CC
- bcs :+
- jmp @fail
- :
- .endmacro
-
- .macro FAIL_NE
- beq :+
- jmp @fail
- :
- .endmacro
-
- .macro FAIL_EQ
- bne :+
- jmp @fail
- :
- .endmacro
-
- .segment "LOADADDR"
- .word $1C01
-
- .segment "EXEHDR"
- .word basic_end
- .word 10
- .byte $9E
- .byte "7181"
- .byte $00
- basic_end:
- .word $0000
-
- .segment "MAILBOX"
- .res MB_SIZE
-
- .segment "ZEROPAGE"
- tptr: .res 2
-
- .segment "STARTUP"
- .export test_entry, test_end
- test_entry:
- php
- sei
- ldx #MB_SIZE - 1
- lda #$00
- @clr: sta MB_BASE,x
- dex
- bpl @clr
- lda #MB_MAGIC0_VALUE
- sta MB_MAGIC0
- lda #MB_MAGIC1_VALUE
- sta MB_MAGIC1
- lda #MB_PROD_PROGRAM
- sta MB_PRODUCER
- lda #MB_ST_RUNNING
- sta MB_STATUS
-
- lda MMU_CR
- sta saved_cr
- lda #CR_RAM0_KERNAL
- sta MMU_CR
-
- lda #PR_CLEAR
- jsr pr_char
- TEXT title, 17
- jsr pr_cr
-
- ; ------------------------------------------------------------- init
- PHASE 1
- lda #$00
- ldx #>HEAP_TEST_BASE
- ldy #HEAP_TEST_PAGES
- jsr heap_init
- FAIL_CS
- lda heap_free_total
- cmp #$00
- FAIL_NE
- lda heap_free_total+1
- cmp #$10
- FAIL_NE
- lda heap_free_head
- cmp #$00
- FAIL_NE
- lda heap_free_head+1
- cmp #$40
- FAIL_NE
- lda HEAP_TEST_BASE
- cmp #$00
- FAIL_NE
- lda HEAP_TEST_BASE+1
- cmp #$10
- FAIL_NE
- lda HEAP_TEST_BASE+2
- ora HEAP_TEST_BASE+3
- FAIL_NE
- lda #$01
- sta MB_DATA+0
-
- ; ------------------------------------------- one allocation and free
- PHASE 2
- lda #32
- ldx #0
- jsr heap_alloc
- FAIL_CS
- cmp #$04
- FAIL_NE
- cpx #$40
- FAIL_NE
- lda heap_free_total
- cmp #$DC
- FAIL_NE
- lda heap_free_total+1
- cmp #$0F
- FAIL_NE
- lda HEAP_TEST_BASE
- cmp #$24
- FAIL_NE
- lda HEAP_TEST_BASE+1
- cmp #$80
- FAIL_NE
- lda HEAP_TEST_BASE+2
- cmp #$5A
- FAIL_NE
- lda HEAP_TEST_BASE+3
- cmp #$A5
- FAIL_NE
- ldy #0
- @zero: lda HEAP_TEST_BASE+4,y
- FAIL_NE
- iny
- cpy #32
- bne @zero
- lda #$A5
- ldy #0
- @fill: sta HEAP_TEST_BASE+4,y
- iny
- cpy #32
- bne @fill
- lda #$04
- ldx #$40
- jsr heap_free
- FAIL_CS
- lda heap_free_total
- cmp #$00
- FAIL_NE
- lda heap_free_total+1
- cmp #$10
- FAIL_NE
- lda HEAP_TEST_BASE
- cmp #$00
- FAIL_NE
- lda HEAP_TEST_BASE+1
- cmp #$10
- FAIL_NE
- lda HEAP_TEST_BASE+2
- ora HEAP_TEST_BASE+3
- FAIL_NE
- lda #$01
- sta MB_DATA+1
-
- ; ------------------------------------------ split and coalesce twice
- PHASE 3
- lda #16
- ldx #0
- jsr heap_alloc
- FAIL_CS
- cmp #$04
- FAIL_NE
- cpx #$40
- FAIL_NE
- lda heap_free_total
- cmp #$EC
- FAIL_NE
- lda heap_free_total+1
- cmp #$0F
- FAIL_NE
- lda HEAP_TEST_BASE
- cmp #$14
- FAIL_NE
- lda HEAP_TEST_BASE+1
- cmp #$80
- FAIL_NE
- lda HEAP_TEST_BASE+$14
- cmp #$EC
- FAIL_NE
- lda HEAP_TEST_BASE+$15
- cmp #$0F
- FAIL_NE
-
- lda #16
- ldx #0
- jsr heap_alloc
- FAIL_CS
- cmp #$18
- FAIL_NE
- cpx #$40
- FAIL_NE
- lda heap_free_total
- cmp #$D8
- FAIL_NE
- lda heap_free_total+1
- cmp #$0F
- FAIL_NE
- lda HEAP_TEST_BASE+$28
- cmp #$D8
- FAIL_NE
- lda HEAP_TEST_BASE+$29
- cmp #$0F
- FAIL_NE
-
- lda #$04
- ldx #$40
- jsr heap_free
- FAIL_CS
- lda #$18
- ldx #$40
- jsr heap_free
- FAIL_CS
- lda heap_free_total
- cmp #$00
- FAIL_NE
- lda heap_free_total+1
- cmp #$10
- FAIL_NE
- lda HEAP_TEST_BASE
- cmp #$00
- FAIL_NE
- lda HEAP_TEST_BASE+1
- cmp #$10
- FAIL_NE
- lda HEAP_TEST_BASE+2
- ora HEAP_TEST_BASE+3
- FAIL_NE
- lda #$01
- sta MB_DATA+2
-
- ; ---------------------------------------------------- stress pass
- PHASE 4
- lda #0
- sta stress_i
- @alloc:
- lda #64
- ldx #0
- jsr heap_alloc
- FAIL_CS
- sta tptr
- stx tptr+1
- ldx stress_i
- lda tptr
- sta ptrs,x
- lda tptr+1
- sta ptrs+1,x
- ldy #0
- lda tptr
- sta (tptr),y
- ldy #63
- lda #$A5
- sta (tptr),y
- lda stress_i
- clc
- adc #2
- sta stress_i
- cmp #32
- bne @alloc
-
- lda #0
- sta stress_i
- @verify:
- ldx stress_i
- lda ptrs,x
- sta tptr
- lda ptrs+1,x
- sta tptr+1
- ldy #0
- lda (tptr),y
- cmp tptr
- FAIL_NE
- ldy #63
- lda (tptr),y
- cmp #$A5
- FAIL_NE
- lda stress_i
- clc
- adc #2
- sta stress_i
- cmp #32
- bne @verify
-
- lda #0
- sta stress_i
- @free_even:
- ldx stress_i
- lda ptrs,x
- sta tptr
- lda ptrs+1,x
- sta tptr+1
- lda tptr
- ldx tptr+1
- jsr heap_free
- FAIL_CS
- lda stress_i
- clc
- adc #4
- sta stress_i
- cmp #32
- bne @free_even
-
- lda #30
- sta stress_i
- @free_odd:
- ldx stress_i
- lda ptrs,x
- sta tptr
- lda ptrs+1,x
- sta tptr+1
- lda tptr
- ldx tptr+1
- jsr heap_free
- FAIL_CS
- lda stress_i
- sec
- sbc #4
- sta stress_i
- bcs @free_odd
- lda heap_free_total
- cmp #$00
- FAIL_NE
- lda heap_free_total+1
- cmp #$10
- FAIL_NE
- lda HEAP_TEST_BASE
- cmp #$00
- FAIL_NE
- lda HEAP_TEST_BASE+1
- cmp #$10
- FAIL_NE
- lda #$01
- sta MB_DATA+3
-
- ; --------------------------------------------------- double free
- PHASE 5
- lda #16
- ldx #0
- jsr heap_alloc
- FAIL_CS
- lda #$04
- ldx #$40
- jsr heap_free
- FAIL_CS
- lda #$04
- ldx #$40
- jsr heap_free
- FAIL_CC
- lda heap_error
- cmp #HEAP_ERR_DOUBLE
- FAIL_NE
- lda heap_free_total
- cmp #$00
- FAIL_NE
- lda heap_free_total+1
- cmp #$10
- FAIL_NE
- lda #$01
- sta MB_DATA+4
-
- ; ------------------------------------------------ corrupt header
- PHASE 6
- lda #16
- ldx #0
- jsr heap_alloc
- FAIL_CS
- lda #$00
- sta HEAP_TEST_BASE+2
- sta HEAP_TEST_BASE+3
- lda #$04
- ldx #$40
- jsr heap_free
- FAIL_CC
- lda heap_error
- cmp #HEAP_ERR_CORRUPT
- FAIL_NE
- lda heap_free_total
- cmp #$EC
- FAIL_NE
- lda heap_free_total+1
- cmp #$0F
- FAIL_NE
- lda #$5A
- sta HEAP_TEST_BASE+2
- lda #$A5
- sta HEAP_TEST_BASE+3
- lda #$04
- ldx #$40
- jsr heap_free
- FAIL_CS
- lda heap_free_total
- cmp #$00
- FAIL_NE
- lda heap_free_total+1
- cmp #$10
- FAIL_NE
- lda #$01
- sta MB_DATA+5
-
- ; ---------------------------------------- exhaustion and integrity
- PHASE 7
- lda #0
- sta stress_i
- @ex_alloc:
- lda #128
- ldx #0
- jsr heap_alloc
- FAIL_CS
- sta tptr
- stx tptr+1
- ldx stress_i
- lda tptr
- sta ptrs,x
- lda tptr+1
- sta ptrs+1,x
- ldy #0
- lda #$C3
- sta (tptr),y
- ldy #127
- lda #$A5
- sta (tptr),y
- lda stress_i
- clc
- adc #2
- sta stress_i
- cmp #6
- bne @ex_alloc
- lda heap_free_total
- cmp #$74
- FAIL_NE
- lda heap_free_total+1
- cmp #$0E
- FAIL_NE
-
- lda #$00
- ldx #$10
- jsr heap_alloc
- FAIL_CC
- lda heap_error
- cmp #HEAP_ERR_OOM
- FAIL_NE
- lda heap_free_total
- cmp #$74
- FAIL_NE
- lda heap_free_total+1
- cmp #$0E
- FAIL_NE
-
- lda #0
- sta stress_i
- @ex_verify:
- ldx stress_i
- lda ptrs,x
- sta tptr
- lda ptrs+1,x
- sta tptr+1
- ldy #0
- lda (tptr),y
- cmp #$C3
- FAIL_NE
- ldy #127
- lda (tptr),y
- cmp #$A5
- FAIL_NE
- lda stress_i
- clc
- adc #2
- sta stress_i
- cmp #6
- bne @ex_verify
-
- lda #0
- sta stress_i
- @ex_free:
- ldx stress_i
- lda ptrs,x
- sta tptr
- lda ptrs+1,x
- sta tptr+1
- lda tptr
- ldx tptr+1
- jsr heap_free
- FAIL_CS
- lda stress_i
- clc
- adc #2
- sta stress_i
- cmp #6
- bne @ex_free
- lda heap_free_total
- cmp #$00
- FAIL_NE
- lda heap_free_total+1
- cmp #$10
- FAIL_NE
- lda HEAP_TEST_BASE
- cmp #$00
- FAIL_NE
- lda HEAP_TEST_BASE+1
- cmp #$10
- FAIL_NE
- lda #$01
- sta MB_DATA+6
- lda #$01
- sta MB_DATA+7
-
- TEXT heap_ok, 7
- jsr pr_cr
- lda #FLT_HEAP
- ldx #$00
- ldy #$40
- jsr flt_report
- jmp @done
-
- @fail:
- lda #MB_ST_FAIL
- sta MB_STATUS
- @done:
- lda saved_cr
- sta MMU_CR
- plp
- rts
-
- .segment "RODATA"
- title: .byte "NOVA128 HEAP TEST"
- heap_ok: .byte "HEAP OK"
-
- .segment "BSS"
- saved_cr: .res 1
- stress_i: .res 1
- ptrs: .res 32
- test_end:
|