Created
December 6, 2024 01:42
-
-
Save taotao54321/22fe89edf7539032e98a4a3b0037dd88 to your computer and use it in GitHub Desktop.
6502 の除算ルーチンに時々見られる誤りの検証 (NES 用)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MEMORY { | |
INES: start=0, size=$10, fill=yes, fillval=0, file=%O; | |
PRG: start=$C000, size=$4000, fill=yes, fillval=0, file=%O; | |
} | |
SEGMENTS { | |
INES: load=INES, type=ro; | |
PRG: load=PRG, type=ro; | |
VECTORS: load=PRG, type=ro, start=$FFFA; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
VRAM_MIRROR_H = 0 << 0 | |
VRAM_MIRROR_V = 1 << 0 | |
;--------------------------------------------------------------------- | |
MAPPER = 0 | |
VRAM_MIRROR = VRAM_MIRROR_H | |
PRG_COUNT = 1 | |
CHR_COUNT = 0 | |
.segment "INES" | |
.literal "NES", $1A | |
.byte PRG_COUNT | |
.byte CHR_COUNT | |
.byte VRAM_MIRROR | (MAPPER << 4) | |
.byte MAPPER & $F0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.PHONY: all verify clean | |
CMP := cmp | |
CA65 := ca65 | |
LD65 := ld65 | |
MKDIR := mkdir | |
OUT_DIR := build | |
OUT_NES := $(OUT_DIR)/division.nes | |
OUT_DBG := $(OUT_DIR)/division.dbg | |
OUT_LBL := $(OUT_DIR)/division.lbl | |
LD65_SCRIPT := division.ld65 | |
OBJS := \ | |
$(OUT_DIR)/ines.o \ | |
$(OUT_DIR)/prg.o | |
all: $(OUT_NES) | |
$(OUT_NES): $(LD65_SCRIPT) $(OBJS) | |
$(LD65) --config $(LD65_SCRIPT) --dbgfile $(OUT_DBG) -Ln $(OUT_LBL) -o $@ $(OBJS) | |
$(OUT_DIR)/%.o: %.s65 | $(OUT_DIR)/. | |
$(CA65) --debug-info -o $@ $< | |
$(OUT_DIR)/.: | |
$(MKDIR) -p $@ | |
clean: | |
-$(RM) -r $(OUT_DIR) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;===================================================================== | |
; 6502 の除算ルーチンに時々見られる誤りの検証 | |
;===================================================================== | |
; 全ての除算ルーチンは以下のインターフェースを持つ: | |
; | |
; 引数 | |
; lhs_quot 左辺 (u16le) | |
; rhs 右辺 (u8) | |
; | |
; 戻り値 | |
; lhs_quot 商 (u16le) | |
; rem 余り (u8) | |
; | |
; 左辺と商については同一のメモリ領域を使い回している。 | |
lhs_quot := $00 | |
rhs := $02 | |
rem := $03 | |
;--------------------------------------------------------------------- | |
.segment "PRG" | |
;--------------------------------------------------------------------- | |
;;; RESET ハンドラ。 | |
Reset: | |
@LHS = $8000 | |
@RHS = $81 | |
lda #<@LHS | |
sta lhs_quot | |
lda #>@LHS | |
sta lhs_quot+1 | |
lda #@RHS | |
sta rhs | |
jsr DivCorrect | |
lda #<@LHS | |
sta lhs_quot | |
lda #>@LHS | |
sta lhs_quot+1 | |
lda #@RHS | |
sta rhs | |
jsr DivWrongA | |
lda #<@LHS | |
sta lhs_quot | |
lda #>@LHS | |
sta lhs_quot+1 | |
lda #@RHS | |
sta rhs | |
jsr DivWrongB | |
@loop_forever: | |
jmp @loop_forever | |
;;; 正しい u16 / u8 除算。 | |
DivCorrect: | |
lda #0 | |
sta rem | |
ldx #16 | |
asl lhs_quot | |
rol lhs_quot+1 | |
@loop: | |
; rem がオーバーフローしたら rhs を減算。 | |
rol rem | |
bcs @subtract | |
; rem >= rhs ならば rhs を減算。 | |
lda rem | |
cmp rhs | |
bcc @next | |
@subtract: | |
; ここでは常にキャリーフラグが真。 | |
lda rem | |
sbc rhs | |
sta rem | |
sec ; rem がオーバーフローした場合、これが必要。 | |
@next: | |
rol lhs_quot | |
rol lhs_quot+1 | |
dex | |
bne @loop | |
rts | |
;;; 正しくない u16 / u8 除算 (余りのオーバーフローを考慮していない)。 | |
DivWrongA: | |
lda #0 | |
sta rem | |
ldx #16 | |
asl lhs_quot | |
rol lhs_quot+1 | |
@loop: | |
; XXX: ここでのオーバーフローを考慮していない! | |
rol rem | |
lda rem | |
cmp rhs | |
bcc @next | |
@subtract: | |
; ここでは常にキャリーフラグが真。 | |
lda rem | |
sbc rhs | |
sta rem | |
@next: | |
rol lhs_quot | |
rol lhs_quot+1 | |
dex | |
bne @loop | |
rts | |
;;; 正しくない u16 / u8 除算 (余りのオーバーフロー時、減算後にキャリーフラグをセットしていない)。 | |
DivWrongB: | |
lda #0 | |
sta rem | |
ldx #16 | |
asl lhs_quot | |
rol lhs_quot+1 | |
@loop: | |
rol rem | |
bcs @subtract | |
lda rem | |
cmp rhs | |
bcc @next | |
@subtract: | |
; ここでは常にキャリーフラグが真。 | |
lda rem | |
sbc rhs | |
sta rem | |
; XXX: sbc で必ずキャリーフラグが真になると仮定しているが、rem がオーバーフローした場合これは成り立たない! | |
@next: | |
rol lhs_quot | |
rol lhs_quot+1 | |
dex | |
bne @loop | |
rts | |
Nmi: | |
Irq: | |
rti | |
;--------------------------------------------------------------------- | |
.segment "VECTORS" | |
;--------------------------------------------------------------------- | |
VECTORS: | |
.addr Nmi | |
.addr Reset | |
.addr Irq |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment