diff --git a/src/anti-m.a b/src/anti-m.a index d6fda16..fa44403 100644 --- a/src/anti-m.a +++ b/src/anti-m.a @@ -132,6 +132,8 @@ Tracer bcc BeginTheBoot jsr IDSirius bcc BeginTheBoot + jsr IDProDOS + bcc BeginTheBoot ; [execution falls through here] ; [and runs anyway] @@ -197,3 +199,4 @@ StringTable !src "src/ididsi.a" !src "src/idsirius.a" !src "src/idboot.a" + !src "src/idprodos.a" diff --git a/src/idprodos.a b/src/idprodos.a new file mode 100644 index 0000000..aff548a --- /dev/null +++ b/src/idprodos.a @@ -0,0 +1,193 @@ +; ProDOS tracer +; written by qkumba +; +IDProDOS + lda #8 + ldx #1 + ldy #10 + jsr CompareMemory + !byte $38 ;SEC + !byte $B0,$03 ;BCS *+5 + !byte $4C,$32,$A1 ;JMP $A132 + !byte $86,$43 ;STA $43 + !byte $C9,$03 ;CMP #$03 + bcs @exit + ldy #@ProDOSCallback_e-@ProDOSCallback +- lda @ProDOSCallback-1,y + sta @ProDOSCallbackx-1,y + dey + bne - + lda #$4C + sta $8FC + lda #<@ProDOSCallbackx + sta $8FD + lda #>@ProDOSCallbackx + sta $8FE +@exit + rts + +@ProDOSCallback +!pseudopc $B000 { +@ProDOSCallbackx + lda #$20 + ldx #$30 + ldy #4 + jsr @SearchMemory + !byte $A9,$02 ;LDA #$02 + !byte $91,$14 ;STA ($14),Y + bcs @ProDOS_exit + sta @ProDOS_patch+2 + lda #$EA + ldy #6 +@ProDOS_patch + sta $D100,X + inx + dey + bne @ProDOS_patch +@ProDOS_exit + jmp $2000 + +;------------------------------- +; SearchMemory subroutine +; written by qkumba +; search for a string occurring anywhere +; in the main memory +; #WILDCARD in search string matches any 1 byte +; (like "." character in regular expressions) +; in: A = starting page to search +; X = ending page+1 to search +; Y = string length +; stack = string to find +; out: C clear if string found +; or set if not found +; If C is clear, then +; A = page where string was found +; X = starting offset where string was found +; all other registers and flags clobbered +;------------------------------- +@SearchMemory + + stx @endvalue+1 + sta @search+2 + pla + sta @match_buffer1+1 + sta @match_all+1 + pla + sta @match_buffer1+2 + sta @match_all+2 + tax + sty @match_size1+1 + sty @match_size2+1 + +; fetch last byte to improve search speed + +@match_buffer1 + lda $d1d1,y ; modified at runtime + sta @check_byte1+1 + sta @check_byte2+1 + +; set low part of initial search position + + tya + dey + sty @cont_search+1 + +; set return address + + clc + adc @match_buffer1+1 + tay + bcc @plus01 + inx +@plus01 + txa + pha + tya + pha + +; set match position + + inc @match_all+1 + bne @plus02 + inc @match_all+2 +@plus02 + + lda #<@cont_search-@branch_cont-2 + sta @branch_cont+1 + +; search... + +@cont_search + ldy #$d1 ; modified at runtime + +@search + lda $d100,y ; modified at runtime + iny + beq @check_end + +@check_byte1 + cmp #$d1 ; modified at runtime + bne @search + +; point to first byte + + sty @cont_search+1 + +@check_match + tya + +@match_size1 + sbc #$d1 ; modified at runtime + sta @match_buffer2+1 + ldx @search+2 + bcs @plus03 + dex +@plus03 + stx @match_buffer2+2 + ldy #$00 + +@match_all + lda $d1d1,y ; modified at runtime + cmp #WILDCARD + beq @found_wild + +@match_buffer2 + cmp $d1d1,y ; modified at runtime + +@branch_cont + bne @cont_search + +@found_wild + iny + +@match_size2 + cpy #$d1 ; modified at runtime + bne @match_all + +; point to start of match + + ldx @match_buffer2+1 + lda @match_buffer2+2 + clc + rts + +; cold path + +@check_end + inc @search+2 + ldx @search+2 +@endvalue + cpx #$D1 + bne @check_byte1 + ldx #<@all_done_set-@branch_cont-2 + stx @branch_cont+1 + +@check_byte2 + cmp #$d1 ; modified at runtime + beq @check_match + +@all_done_set + sec + rts +} +@ProDOSCallback_e