This is a post about how wAx's functionality can be extended with user tools. wAx doesn't have a diff tool built-in. But it has a vector to "plug in" new code and use it as a wAx tool. So I wrote a diff tool, which can be loaded from disk and installed. First, here's the installation process and example usage:
The < tool is used to load the code, with the load tool telling you where the code starts and ends. The vector at $0005/$0006 is then set to point to the loaded tool at $7900. Then I set up a test case (two lines of text) and invoke the tool. This tool takes an address range, and then a target address. It compares the range byte-for-byte with the target, and tells you where the matches (in green) and differences (in red) start, and how many bytes long they are.
The code for this plug-in is below. The PDF manual documents the wAx API, the subroutines used in the tool. For the most part, they're very simple input/output routines for adding text, advancing pointers, parsing parameters, converting bytes to hex output.
I'll have a variety of examples on the Wiki. Also, several of these tools will be included in the cartridge version, since I'm only using half of a 2764 for wAx itself. It's not likely that I'm going to develop 4K of tools, but there will be some useful easter eggs.
Code: Select all
; wAx Diff Tool
; 'start end target
; Compares bytes from start to end of range (inclusive) and reports
; each byte that does not match the same offset in target.
; wAx API
EFADDR = $a6 ; Effective Address
X_PC = $03 ; External Persistent Counter
RANGE_END = $0254 ; End of range
Buff2Byte = $7000 ; Get 8-bit hex number from input buffer to A
CharGet = $7003 ; Get character from input buffer to A
CharOut = $7006 ; Write character in A to output buffer
Hex = $7009 ; Write value in A to output buffer 8-bit hex
IncAddr = $700c ; Increment Effective Address, store value in A
IncPC = $700f ; Increment Persistent Counter
Lookup = $7012 ; Lookup 6502 instruction with opcode in A
PrintBuff = $7015 ; Flush output buffer to screen
ResetIn = $7018 ; Reset input buffer index
ResetOut = $701b ; Reset output buffer index
ShowAddr = $701e ; Write Effective Address to output buffer
ShowPC = $7021 ; Write Persistent Counter to output buffer
; Diff tool workspace
STATUS = $0247 ; $00 = Non-Matching, $80 = Matching
COUNT = $0248 ; Count of unmatched/matched bytes so far
*=$7900
Main: bcc error ; Error if the first address is no good
jsr Buff2Byte ; Get high byte of range end
bcc error ; ,,
sta RANGE_END+1 ; ,,
jsr Buff2Byte ; Get low byte of range end
bcc error ; ,,
sta RANGE_END ; ,,
jsr Buff2Byte ; Get high byte of compare start
bcc error ; ,,
sta X_PC+1 ; ,,
jsr Buff2Byte ; Get low byte of compare start
bcc error ; ,,
sta X_PC ; ,,
lda #$00 ; Reset status and counter
sta STATUS ; ,,
sta COUNT ; ,,
sta COUNT+1 ; ,,
bcs Start ; Setup OK, do compare
error: jmp $cf08 ; ?SYNTAX ERROR, warm start
; Start comparison
Start: jsr StartLine ; Start address line
inc RANGE_END ; Increase the range by 1 for
bne compare ; the comparison
inc RANGE_END+1 ; ,,
compare: lda EFADDR+1 ; Is the effective address in
cmp RANGE_END+1 ; the compare range?
bcc in_range ; ,,
lda EFADDR ; ,,
cmp RANGE_END ; ,,
bcc in_range ; If so, check for byte match
done: jsr Toggle ; Toggle to show the right color
jsr EndLine ; Show the last result count
rts ; Done!
in_range: ldx #$00 ; Compare EA to PC
lda (EFADDR,x) ; ,,
cmp (X_PC,x) ; ,,
bne differs
matches: lda STATUS ; If the byte matches, and the previous byte
beq show_last ; differed, then toggle the status and reset
bne next
differs: lda STATUS ; If the byte differs, and the previous byte
bne show_last ; matched, then toggle the status and reset
beq next
show_last: jsr Toggle
jsr EndLine ; Show the count
lda #$00 ; Reset the counter
sta COUNT ; ,,
sta COUNT+1 ; ,,
jsr StartLine ; Start a new line
next: inc COUNT ; Increment the count of match/unmatch
bne inc_mem ; ,,
inc COUNT+1 ; ,,
inc_mem: jsr IncPC ; Increment the comparison counters
jsr IncAddr ; ,,
jsr $ffe1 ; Check STOP key
beq done ; End the comparison if STOP
jmp compare ; Do the next comparison
Toggle: lda STATUS
bne toggle_off
lda #$80
.byte $34 ; DOP (skip byte)
toggle_off: asl
sta STATUS
rts
; Start Line
; Reset the output buffer, and add the addresses
StartLine: jsr ResetOut
lda #"$"
jsr CharOut
jsr ShowAddr
lda #","
jsr CharOut
jsr ShowPC
lda #":"
jsr CharOut
rts
; End Line
; Complete the line by showing the count in red (differences) or
; green (matches)
EndLine: lda COUNT ; If the count is zero, don't
bne report ; finish the buffer, because it's
lda COUNT+1 ; probably the first group of bytes
bne report ; ,,
rts ; ,,
report: lda $0286 ; Store current color
pha ; ,,
lda STATUS
beq green
red: lda #$1c ; Red
.byte $3c ; TOP (skip word)
green: lda #$1e ; Green
jsr CharOut
lda COUNT+1 ; Show number of matches/no matches
jsr Hex ; before the change
lda COUNT ; ,,
jsr Hex ; ,,
jsr PrintBuff ; ,,
pla ; Restore original color
sta $0286 ; ,,
rts