HeaderTitle EQUS "\"MISCINSTRS\"" include "common/defines.inc" include "common/header.inc" include "common/functions.inc" ; Output legend: ; A failed, B failed: white ; A passed, B failed: light gray ; A failed, B passed: dark gray ; A passed, B passed: black ; ; Top row: ; 1a - BIT (against set bits) ; 1b - BIT (against unset bits) ; 2a - RLC (zero flag) ; 2b - RLC (carry flag) ; 3a - RL (zero flag) ; 3b - RL (carry flag) ; 4a - SLA (zero flag) ; 4b - SLA (carry flag) ; 5a - RRC (zero flag) ; 5b - RRC (carry flag) ; 6a - RR (zero flag) ; 6b - RR (carry flag) ; 7a - SRA (zero flag) ; 7b - SRA (carry flag) ; 8a - SRL (zero flag) ; 8b - SRL (carry flag) ; 9a - RLCA (zero flag) ; 9b - RLCA (carry flag) ; 10a - RLA (zero flag) ; 10b - RLA (carry flag) ; 11a - RRCA (zero flag) ; 11b - RRCA (carry flah) ; 12a - RRA (zero flag) ; 12b - RRA (carry flag) ; ; Bottom row: ; 13a - SWAP (zero flag) ; 13b - SWAP (value) ; 14a - SCF ; 14b - CCF ; 15a - DAA ; 15b - CPL ; 16a - INC r16 ; 16b - DEC r16 ; 17a - ADD ; 17b - ADC ; 18a - SUB ; 18b - SBC ; 19a - LD r16 ; 19b - ADD r16 ; 20a - ADD (HL) ; 20b - ADC (HL) ; 21a - SUB (HL) ; 21b - SBC (HL) ; 22a - LD a16, SP ; 22b - LD HL, SP+r8 ; 23a - LD A, (C) ; 23b - LD (C), A ; 24a - LD SP, HL ; 24b - ADD SP, r8 SECTION "home", ROM0 ProgramStart: call clearLogo _lcdDisable ; Set a proper grayscale palette. ld a, %11100100 ldh [$ff47], a ld hl, $8010 ; BIT ld b, $00 call testBitIsSet call testBitIsUnset call fillTileEx ; RLC ld b, $00 call testRlcZero call testRlcCarry call fillTileEx ; RL ld b, $00 call testRlZero call testRlCarry call fillTileEx ; SLA ld b, $00 call testSlaZero call testSlaCarry call fillTileEx ; RRC ld b, $00 call testRrcZero call testRrcCarry call fillTileEx ; RR ld b, $00 call testRrZero call testRrCarry call fillTileEx ; SRA ld b, $00 call testSraZero call testSraCarry call fillTileEx ; SRL ld b, $00 call testSrlZero call testSrlCarry call fillTileEx ; RLCA ld b, $00 call testRlcaZero call testRlcaCarry call fillTileEx ; RLA ld b, $00 call testRlaZero call testRlaCarry call fillTileEx ; RRCA ld b, $00 call testRrcaZero call testRrcaCarry call fillTileEx ; RRA ld b, $00 call testRraZero call testRraCarry call fillTileEx ; SWAP ld b, $00 call testSwapZero call testSwapValue call fillTileEx ; SCF / CCF ld b, $00 call testScf call testCcf call fillTileEx ; DAA / CPL ld b, $00 call testDaa call testCpl call fillTileEx ; INC r16 / DEC r16 ld b, $00 call testInc16 call testDec16 call fillTileEx ; ADD / ADC ld b, $00 call testAdd call testAdc call fillTileEx ; SUB / SBC ld b, $00 call testSub call testSbc call fillTileEx ; LD r16 / ADD r16 ld b, $00 call testLd16 push hl call testAdd16 ; clobbers HL pop hl call fillTileEx ; ADD (HL) / ADC (HL) ld b, $00 push hl call testAddMem call testAdcMem pop hl ; both functions clobber HL call fillTileEx ; SUB (HL) / SBC (HL) ld b, $00 push hl call testSubMem call testSbcMem pop hl ; both functions clobber HL call fillTileEx ; LD a16, SP / LD HL, SP+r8 ld b, $00 push hl call testLdAddrSp call testLdHlSpVal pop hl ; both functions clobber HL call fillTileEx ; LD A, (C) / LD (C), A ld b, $00 call testLdAHC call testLdHCA call fillTileEx ; LD SP, HL / ADD SP, r8 ; These can easily cause the system to crash, so draw the screen first. ; We can plot the last block next frame (if we make it that far). push hl ld b, $00 _lcdEnable call testLdSpHl call testAddSpR _lcdDisable pop hl ; Pretty much everything in this section clobbers HL :) call fillTileEx call drawGrid _lcdEnable .loop: jr .loop SECTION "tests", ROM0[$400] testBitIsSet: ; 1a ld a, %00000001 bit 0, a ret z ld a, %00000010 bit 1, a ret z ld a, %00000100 bit 2, a ret z ld a, %00001000 bit 3, a ret z ld a, %00010000 bit 4, a ret z ld a, %00100000 bit 5, a ret z ld a, %01000000 bit 6, a ret z ld a, %10000000 bit 7, a ret z set 0, b ; I guess we're testing SET here, too! :) ret testBitIsUnset: ; 1b ld a, %11111110 bit 0, a ret nz ld a, %11111101 bit 1, a ret nz ld a, %11111011 bit 2, a ret nz ld a, %11110111 bit 3, a ret nz ld a, %11101111 bit 4, a ret nz ld a, %11011111 bit 5, a ret nz ld a, %10111111 bit 6, a ret nz ld a, %01111111 bit 7, a ret nz set 1, b ret testRlcZero: ; 2a ld a, 0 rlc a ret nz ld a, $10 rlc a ret z set 0, b ret testRlcCarry: ; 2b ld a, 1 rlc a ret c ; carry flag check (should be unset) ld a, %10000000 rlc a ret nc ; carry flag check (should be set) bit 0, a ret z ; LSB check (should be 1) rlc a ret c ; carry flag check (should be cleared) bit 0, a ret nz ; LSB check (should be 0) bit 1, a ret z ; rotation check (bit 1 should be 1) set 1, b ret testRlZero: ; 3a ld a, 0 rl a ret nz ld a, $10 rl a ret z set 0, b ret testRlCarry: ; 3b ld a, 1 rl a ret c ; carry flag check (should be unset) ld a, %10000000 rl a ret nc ; carry flag check (should be set) bit 0, a ret nz ; LSB check (should be 0) rl a ret c ; carry flag check (should be cleared) bit 0, a ret z ; LSB check (should be 1) bit 1, a ret nz ; rotation check (bit 1 should be 0) set 1, b ret testSlaZero: ; 4a ld a, 0 sla a ret nz ld a, $10 sla a ret z set 0, b ret testSlaCarry: ; 4b ld a, 1 sla a ret c ; carry flag check (should be unset) ld a, %10000000 sla a ret nc ; carry flag check (should be set) bit 0, a ret nz ; LSB check (should be 0) sla a ret c ; carry flag check (should be unset) ret nz ; zero flag check (should be set) set 1, b ret testRrcZero: ; 5a ld a, 0 rrc a ret nz ld a, $10 rrc a ret z set 0, b ret testRrcCarry: ; 5b ld a, $10 rrc a ret c ; carry flag check (should be unset) ld a, 1 rrc a ret nc ; carry flag check (should be set) bit 7, a ret z ; MSB check (should be 1) rrc a ret c ; carry flag check (should be unset) bit 7, a ret nz ; MSB check (should be 0) bit 6, a ret z ; Bit 6 check (should be 1) set 1, b ret testRrZero: ; 6a ld a, 0 rr a ret nz ld a, $10 rr a ret z set 0, b ret testRrCarry: ; 6b ld a, $10 rr a ret c ; carry flag check (should be unset) ld a, 1 rr a ret nc ; carry flag check (should be set) bit 7, a ret nz ; MSB check (should be 0) rr a ret c ; carry flag check (should be unset) bit 7, a ret z ; MSB check (should be 1) bit 6, a ret nz ; Bit 6 check (should be 0) set 1, b ret testSraZero: ; 7a ld a, 0 sra a ret nz ld a, $10 sra a ret z set 0, b ret testSraCarry: ; 7b ld a, $10 sra a ret c ; carry flag check (should be unset) ld a, 1 sra a ret nc ; carry flag check (should be set) bit 7, a ret nz ; MSB check (should be 0) sra a ret c ; carry flag check (should be unset) bit 7, a ret nz ; MSB check (should be 0) ld a, $81 sra a ret nc ; carry flag check (should be set) bit 7, a ret z ; MSB check (should be 1) bit 6, a ret z ; Bit 6 check (should be 1) bit 5, a ret nz ; Bit 5 check (should be 0) sra a ret c ; carry flag check (should be unset) bit 7, a ret z ; MSB check (should be 1) bit 6, a ret z ; Bit 6 check (should be 1) bit 5, a ret z ; Bit 5 check (should be 1) set 1, b ret testSrlZero: ; 8a ld a, 0 srl a ret nz ld a, $10 srl a ret z set 0, b ret testSrlCarry: ; 8b ld a, $10 srl a ret c ; carry flag check (should be unset) ld a, 1 srl a ret nc ; carry flag check (should be set) bit 7, a ret nz ; MSB check (should be 0) srl a ret c ; carry flag check (should be unset) bit 7, a ret nz ; MSB check (should be 0) set 1, b ret testRlcaZero: ; 9a ld a, 0 rlca ret z ld a, $10 rlca ret z set 0, b ret testRlcaCarry: ; 9b ld a, 1 rlca ret c ; carry flag check (should be unset) ld a, %10000000 rlca ret nc ; carry flag check (should be set) bit 0, a ret z ; LSB check (should be 1) rlca ret c ; carry flag check (should be cleared) bit 0, a ret nz ; LSB check (should be 0) bit 1, a ret z ; rotation check (bit 1 should be 1) set 1, b ret testRlaZero: ; 10a ld a, 0 rla ret z ld a, $10 rla ret z set 0, b ret testRlaCarry: ; 10b ld a, 1 rla ret c ; carry flag check (should be unset) ld a, %10000000 rla ret nc ; carry flag check (should be set) bit 0, a ret nz ; LSB check (should be 0) rla ret c ; carry flag check (should be cleared) bit 0, a ret z ; LSB check (should be 1) bit 1, a ret nz ; rotation check (bit 1 should be 0) set 1, b ret testRrcaZero: ; 11a ld a, 0 rrca ret z ld a, $10 rrca ret z set 0, b ret testRrcaCarry: ; 11b ld a, $10 rrca ret c ; carry flag check (should be unset) ld a, 1 rrca ret nc ; carry flag check (should be set) bit 7, a ret z ; MSB check (should be 1) rrca ret c ; carry flag check (should be unset) bit 7, a ret nz ; MSB check (should be 0) bit 6, a ret z ; Bit 6 check (should be 1) set 1, b ret testRraZero: ; 12a ld a, 0 rra ret z ld a, $10 rra ret z set 0, b ret testRraCarry: ; 12b ld a, $10 rra ret c ; carry flag check (should be unset) ld a, 1 rra ret nc ; carry flag check (should be set) bit 7, a ret nz ; MSB check (should be 0) rra ret c ; carry flag check (should be unset) bit 7, a ret z ; MSB check (should be 1) bit 6, a ret nz ; Bit 6 check (should be 0) set 1, b ret testSwapZero: ; 13a ld a, $F0 swap a ret z ; zero flag check (should be unset) ld a, $00 swap a ret nz ; zero flag check (should be set) set 0, b ret testSwapValue: ; 13b ld a, $4F ld c, $F4 swap a cp c ret nz ; comparison (should be 0) set 1, b ret testScf: ; 14a ld a, $00 add a, a ret c ; sanity check: carry flag (should be unset) scf ret nc ; carry flag check (should be set) set 0, b ret testCcf: ; 14b ld a, $00 add a, a ret c ; sanity check: carry flag (should be unset) ccf ret nc ; carry flag check (should be set) ccf ret c ; carry flag check (should be unset) set 1, b ret testDaa: ; 15a call clearFlags ld a, $00 ld c, $01 daa ret nz ; zero flag check (should be set) call clearFlags ld a, $09 add c daa ld d, $10 cp d ret nz ; zero flag check (should be set) call clearFlags ld a, $0f add c daa ld d, $16 cp d ret nz ; zero flag check (should be set) call clearFlags ld a, $10 sub c daa ld d, $09 cp d ret nz ; zero flag check (should be set) call clearFlags ld a, $0f sub c daa ld d, $0e cp d ret nz ; zero flag check (should be set) call clearFlags ld a, $99 add c daa ret nz ; zero flag check (should be set) ld a, $00 ld d, $00 adc d daa ld d, $01 cp d ret nz ; zero flag check (should be set) set 0, b ret testCpl: ; 15b ld a, %10101010 ld c, %01010101 cpl push af pop de cp c ret nz ; bit flip test (should be zero) bit SubtractFlag, e ret z ; subtract flag check (should be 1) bit HalfCarryFlag, e ret z ; half carry flag check (should be 1) set 1, b ret testInc16: ; 16a ld d, 0 ld e, 0 inc de ld a, 1 cp e ret nz ; zero flag check (should be set) ld d, $00 ld e, $ff inc de ld a, 0 cp e ret nz ; zero flag check (set be set) ld a, 1 cp d ret nz ; zero flag check (should be set) ld d, $ff ld e, $ff inc de ld a, 0 cp e ret nz ; zero flag check (should be set) cp d ret nz ; zero flag check (should be set) set 0, b ret testDec16: ; 16b ld d, 0 ld e, 1 dec de ld a, 0 cp e ret nz ; zero flag check (should be set) ld d, $01 ld e, $00 dec de ld a, $ff cp e ret nz ; zero flag check (should be set) ld a, $00 cp d ret nz ; zero flag check (should be set) ld d, $00 ld e, $00 dec de ld a, $ff cp e ret nz ; zero flag check (should be set) cp d ret nz ; zero flag check (should be set) set 1, b ret testAdd: ; 17a ld c, 1 ld a, 0 ld d, 1 add c ret z ; zero flag check (should be unset) ret c ; carry flag check (should be unset) cp d ret nz ; comparison check (should be set) ld a, $ff ld d, 0 add c ret nc ; carry flag check (should be set) ret nz ; zero flag check (should be set) cp d ret nz ; comparison check (should be set) set 0, b ret testAdc: ; 17b call clearFlags ld c, 1 ld a, 0 ld d, 1 adc c ret z ; zero flag check (should be unset) ret c ; carry flag check (should be unset) cp d ret nz ; comparison check (should be set) ld a, $ff ld d, 0 adc c ret nc ; carry flag check (should be set) ret nz ; zero flag check (should be set) push af cp d ret nz ; comparison check (should be set) pop af ld c, 0 ld d, 1 adc c ret c ; carry flag check (should be unset) ret z ; zero flag check (should be unset) cp d ret nz ; comparison check (should be set) set 1, b ret testSub: ; 18a ld c, 1 ld a, 1 ld d, 0 sub c ret c ; carry flag check (should be unset) ret nz ; zero flag check (should be set) cp d ret nz ; comparison check (should be set) ld d, $ff sub c ret nc ; carry flag check (should be set) ret z ; zero flag check (should be unset) cp d ret nz ; comparison check (should be set) set 0, b ret testSbc: ; 18b call clearFlags ld c, 1 ld a, 1 ld d, 0 sbc c ret c ; carry flag check (should be unset) ret nz ; zero flag check (should be set) cp d ret nz ; comparison check (should be set) ld d, $ff sbc c ret nc ; carry flag check (should be set) ret z ; zero flag check (should be unset) push af cp d ret nz ; comparison check (should be set) pop af ld c, 0 ld d, $fe sbc c ret c ; carry flag check (should be unset) ret z ; zero flag check (should be unset) cp d ret nz ; comparison check (should be set) set 1, b ret testLd16: ; 19a ld de, $1234 ld a, $12 cp d ret nz ; comparison check (should be set) ld a, $34 cp e ret nz ; comparison check (should be set) set 0, b ret testAdd16: ; 19b (clobbers HL) ld de, $1234 ld hl, $2143 add hl, de ld a, $33 cp h ret nz ; comparison check (should be set) ld a, $77 cp l ret nz ; comparison check (should be set) ld hl, $fefe ld de, $1212 add hl, de ; $fefe + $1212 = $11110 & $1111 = $1110 ld a, $11 cp h ret nz ; comparison check (should be set) ld a, $10 cp l ret nz ; comparison check (should be set) set 1, b ret testAddMem: ; 20a (clobbers HL) ld hl, $c000 ld [hl], 1 ld a, 0 ld d, 1 add [hl] ret z ; zero flag check (should be unset) ret c ; carry flag check (should be unset) cp d ret nz ; comparison check (should be set) ld a, $ff ld d, 0 add [hl] ret nc ; carry flag check (should be set) ret nz ; zero flag check (should be set) cp d ret nz ; comparison check (should be set) set 0, b ret testAdcMem: ; 20b (clobbers HL) call clearFlags ld hl, $c000 ld [hl], 1 ld a, 0 ld d, 1 adc [hl] ret z ; zero flag check (should be unset) ret c ; carry flag check (should be unset) cp d ret nz ; comparison check (should be set) ld a, $ff ld d, 0 adc [hl] ret nc ; carry flag check (should be set) ret nz ; zero flag check (should be set) push af cp d ret nz ; comparison check (should be set) pop af ld [hl], 0 ld d, 1 adc [hl] ret c ; carry flag check (should be unset) ret z ; zero flag check (should be unset) cp d ret nz ; comparison check (should be set) set 1, b ret testSubMem: ; 21a (clobbers HL) ld hl, $c000 ld [hl], 1 ld a, 1 ld d, 0 sub [hl] ret c ; carry flag check (should be unset) ret nz ; zero flag check (should be set) cp d ret nz ; comparison check (should be set) ld d, $ff sub [hl] ret nc ; carry flag check (should be set) ret z ; zero flag check (should be unset) cp d ret nz ; comparison check (should be set) set 0, b ret testSbcMem: ; 21b (clobbers HL) call clearFlags ld hl, $c000 ld [hl], 1 ld a, 1 ld d, 0 sbc [hl] ret c ; carry flag check (should be unset) ret nz ; zero flag check (should be set) cp d ret nz ; comparison check (should be set) ld d, $ff sbc [hl] ret nc ; carry flag check (should be set) ret z ; zero flag check (should be unset) push af cp d ret nz ; comparison check (should be set) pop af ld [hl], 0 ld d, $fe sbc [hl] ret c ; carry flag check (should be unset) ret z ; zero flag check (should be unset) cp d ret nz ; comparison check (should be set) set 1, b ret testLdAddrSp: ; 22a (clobbers HL) ld hl, 0 add hl, sp ld [$ff80], sp ld a, [$ff80] cp l ret nz ; comparison check (should be set) ld a, [$ff81] cp h ret nz ; comparison check (should be set) set 0, b ret testLdHlSpVal: ; 22b (clobbers HL) ld hl, 0 add hl, sp ld d, h ld e, l ld hl, sp+1 inc de ld a, d cp h ret nz ; comparison check (should be set) ld a, e cp l ret nz ; comparison check (should be set) ld hl, 0 add hl, sp ld d, h ld e, l ld hl, sp-1 dec de ld a, d cp h ret nz ; comparison check (should be set) ld a, e cp l ret nz ; comparison check (should be set) set 1, b ret testLdAHC: ; 23a ld d, $5f ld a, d ld [$ff80], a ld a, 0 ld c, $80 ldh a, [c] cp d ret nz ; comparison check (should be set) set 0, b ret testLdHCA: ; 23b ld d, $f5 ld a, d ld c, $81 ldh [c], a ld a, 0 ldh a, [$ff81] cp d ret nz ; comparison check (should be set) set 1, b ret testLdSpHl: ; 24a (clobbers HL) ; Save the stack pointer to memory. ld [$ff90], sp ; DANGER ZONE: Modify the stack pointer and push a known value to the ; new location. ld d, $12 ld e, $34 ld hl, $ff82 ld sp, hl push de ; Restore the stack pointer. ld a, [$ff91] ld h, a ld a, [$ff90] ld l, a ld sp, hl ld a, [$ff81] cp d ret nz ; comparison check (should be set) ld a, [$ff80] cp e ret nz ; comparison check (should be unset) set 0, b ret testAddSpR: ; 24b ld [$ff90], sp ; DANGER ZONE: Pretty much everything here. If the stack pointer doesn't ; end up at its starting value this function will not return to the right ; place. ld d, $12 ld e, $34 add sp, -2 push de add sp, 4 set 1, b ret