|
|
nono 0.6.0
; vi:set ts=8: ; ; nono ; Copyright (C) 2023 nono project ; Licensed under nono-license.txt ; ; テストのサブルーチン。 ; 分割アセンブルが出来ないので cat で後ろに追加する。 ; 文字列をメイン側に送る。 ; HL に出力する文字列の先頭番地。文字列は '$' で終端。 ; 文字 '^Z'(0x1a) を出力した時点でプログラムを終了。 ; ホスト側の終了指示も兼ねているのでこの文字自体は送る。 puts: PUSH AF PUSH BC PUSH DE PUSH HL EX DE,HL LD C,09H CALL 0005H POP HL POP DE POP BC POP AF RET ; A レジスタの内容を16進数2文字にして (HL) に書き出す ; Inp: A: 変換したいバイト ; HL: 出力先バッファ ; Out: HL: 入力 +2 され、ここは '\0' が書き出してある。 ; Use: - strhex_byte: PUSH AF PUSH BC LD B,A ; Backup A SRL A SRL A SRL A SRL A ; A >>= 4 CALL strhex_1 LD A,B AND 0FH CALL strhex_1 LD (HL),'$' POP BC POP AF RET strhex_1: CP 0AH JR C,_sh_2 ADD A,7H _sh_2: ADD A,30H LD (HL),A INC HL RET ; A レジスタの内容を16進数2文字にして出力する。 puts_byte: PUSH AF PUSH HL LD HL,_puts_byte_buf CALL strhex_byte LD HL,_puts_byte_buf CALL puts POP HL POP AF RET _puts_byte_buf: defs 4 ; 単項演算のテストの共通部分。 ; IN: HL テストセットの先頭番地 ; (HL + 0).W : テスト名のポインタ ; (HL + 2).W : 実行コード ; (HL + 4).W : テストデータの先頭 ; (HL + 6).B : DAA なら 1 ; OUT: - ; USE: all testrun1: LD DE,testname LD BC,0007H LDIR LD HL,(testname) CALL puts LD IX,(testdata) LD HL,0000H LD (testpos),HL LD (failcount),HL _testrun1_loop: LD HL,(total_count) INC HL LD (total_count),HL LD D,(IX+0) LD E,(IX+1) PUSH DE POP AF LD HL,_testrun1_back PUSH HL ; 戻りアドレス LD HL,(testexec) JP (HL) ; CALL testexec _testrun1_back: PUSH AF POP DE LD A,(IX+2) CP D JR Z,_testrun1_cmp_f CALL fail_a JR _testrun1_next _testrun1_cmp_f: LD A,(IX+3) CP E JR Z,_testrun1_next CALL fail_f _testrun1_next: LD DE,0004H ADD IX,DE LD HL,(testpos) INC HL LD (testpos),HL LD A,(IX+3) ; expflag が 0xff なら終了 CP 0FFH JR NZ,_testrun1_loop LD HL,(failcount) LD A,H OR L RET NZ LD HL,msg_ok CALL puts RET ; A レジスタの結果が異なるのでメッセージを表示 fail_a: LD HL,(testname) CALL puts ; testname PUSH AF LD A,(testpos+1) OR A CALL NZ,puts_byte ; testpos.H LD A,(testpos) CALL puts_byte ; testpos.L LD A,(isdaa) OR A CALL NZ,print_in_daa ; input status if daa LD HL,msg_dst_expects CALL puts ; A expects POP AF CALL puts_byte ; %02x,A LD HL,msg_but CALL puts ; but LD A,D CALL puts_byte ; %02x,D LD HL,msg_eol CALL puts ; . LD HL,(failcount) INC HL LD (failcount),HL RET ; F レジスタの結果が異なるのでメッセージを表示 fail_f: LD HL,(testname) CALL puts ; testname PUSH AF LD A,(testpos+1) OR A CALL NZ,puts_byte ; testpos.H LD A,(testpos) CALL puts_byte ; testpos.L LD A,(isdaa) OR A CALL NZ,print_in_daa ; input status if daa LD HL,msg_f_expects CALL puts ; F expects POP AF CALL puts_byte ; %02x,F LD (daa_f),A LD A,(isdaa) OR A CALL NZ,print_f_daa ; (flags) LD HL,msg_but CALL puts ; but LD A,E CALL puts_byte ; %02x,E LD (daa_f),A LD A,(isdaa) OR A CALL NZ,print_f_daa ; (flags) LD HL,msg_eol CALL puts ; . LD HL,(failcount) INC HL LD (failcount),HL RET ; DAA 用に入力状態を表示。": A=%02x (N=%d H=%d C=%d)" ; IX がテストデータ先頭を指している。 ; AF, HL は破壊可能。 print_in_daa: PUSH BC PUSH DE LD HL,msg_in_a CALL puts ; : A= LD A,(IX+0) CALL puts_byte ; %02x LD E,' ' LD C,02H CALL 0005H ; ' ' LD A,(IX+1) LD (daa_f),A CALL print_f_daa ; (N= H= C=) POP DE POP BC RET ; DAA 用にフラグ詳細を表示。"(N=%d H=%d C=%d)" ; 値は (daa_f) 渡し。 ; AF, HL は破壊可能。 print_f_daa: PUSH BC PUSH DE LD HL,msg_flagn CALL puts ; (N= LD A,(daa_f) AND 02H SRL A ADD A,'0' LD E,A LD C,02H CALL 0005H ; n LD HL,msg_flagh CALL puts ; H= LD A,(daa_f) AND 10H SRL A SRL A SRL A SRL A ADD A,'0' LD E,A LD C,02H CALL 0005H ; h LD HL,msg_flagc CALL puts ; C= LD A,(daa_f) AND 01H ADD A,'0' LD E,A LD C,02H CALL 0005H ; c LD E,29H LD C,02H CALL 0005H ; ) POP DE POP BC RET ; 2項演算のテストの共通部分。 ; IN: HL テストセットの先頭番地 ; (HL + 0).W : テスト名のポインタ ; (HL + 2).W : 実行コード ; (HL + 4).W : テストデータの先頭 ; (HL + 6).B : ここでは 0 ; OUT: - ; USE: all testrun2: LD DE,testname LD BC,0007H LDIR LD HL,(testname) CALL puts LD IX,(testdata) LD HL,0000H LD (testpos),HL LD (failcount),HL _testrun2_loop: LD HL,(total_count) INC HL LD (total_count),HL LD D,(IX+0) LD E,(IX+1) PUSH DE LD D,(IX+2) POP AF LD HL,_testrun2_back PUSH HL ; 戻りアドレス LD HL,(testexec) JP (HL) ; CALL testexec _testrun2_back: PUSH AF POP DE LD A,(IX+3) CP D JR Z,_testrun2_cmp_f CALL fail_a JR _testrun2_next _testrun2_cmp_f: LD A,(IX+4) CP E JR Z,_testrun2_next CALL fail_f _testrun2_next: LD DE,0005H ADD IX,DE LD HL,(testpos) INC HL LD (testpos),HL LD A,(IX+4) ; expflag が 0xff なら終了 CP 0FFH JR NZ,_testrun2_loop LD HL,(failcount) LD A,H OR L RET NZ LD HL,msg_ok CALL puts RET testname: defw 0000H ; テスト名のアドレス testexec: defw 0000H ; 実行コードサブルーチンのアドレス testdata: defw 0000H ; テストデータの先頭番地 isdaa: defb 00H ; DAA なら表示を変更するため testpos: defw 0 ; 今のテストの中の何番目か failcount: defw 0 ; 1セクション中の失敗数 total_count: defw 0 ; テスト実行総数 total_fail: defw 0 ; テスト失敗総数 daa_f: defb 0 ; DAA のフラグ表示用 msg_eol: defb '.', 0DH, 0AH, '$' msg_crlf: defb 0DH, 0AH, '$' msg_ok: defm "OK" defb 0DH, 0AH, '$' msg_dst_expects: defm ": A expects $" msg_but: defm " but $" msg_f_expects: defm ": F expects $" msg_flagn: defm "(N=$" msg_flagh: defm " H=$" msg_flagc: defm " C=$" msg_in_a: defm ": A=$" defb 0, 0, 0 ; padding for disasm
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.