|
Disassembler, disassemble yourself! |
So, I thought it would be a good exercise to write a disassembler for the RIBBBIT65. My plan is to integrate this into the CoreROM, but I have a few fixes and tweaks I want to do first. As it is now, this starts as $1000 and references some constants and code in the CoreROM (e.g. CIOH), so, unfortunately, this won't really output anything without that, but you could stuff your own output routines in there if you were so inclined.
...and, yes, I realize there's a bunch of stuff in here that's redundant... and some hard-coded addresses (rather than constants)... but I thought it might be nice to get something out there.
Originally, I had written this with its own "private" buffer, that it would then copy to the CIOH output buffer, but then I realized that was dumb, and just made this write directly to the CIOH output buffer. Unfortunately, there are still some vestiges of the "private buffer" business in here (constants and such).
Anyway... here it is.
; START BNW CONSTANTS
DBUTIL0 = $50
DBUTIL1 = $51
DBUTIL2 = $52
DBUTIL3 = $53
DBUTIL4 = $54
VWMSGSYS = $0090 ; System Message Vector
VWMSGPRG = $0092 ; Program Message Vector
VWMSGSPC = $0094 ; Special Message Vector
DBCPBTERM = $6237 ; Current Peripheral Buffer Terminate Value
CBSERBRDM = $6238 ; Serial Baud Rate Delay MultiplierDFCLCDLB0 = $6d00 ; Character LCD Line Buffer 0
DFCLCDLB1 = $6d30 ; Character LCD Line Buffer 1
DFCLCDLB2 = $6d60 ; Character LCD Line Buffer 2
DFCLCDLB3 = $6d90 ; Character LCD Line Buffer 3
DFCLCDLB4 = $6dc0 ; Character LCD Line Buffer 4
pfciohobufappendbytestart = $b264 ;EXPR(45668=0xb264) ABS
pfsetcurpstart = $b1c0 ; EXPR(45504=0xb1c0) ABS
pfciohstdentry = $b27f ; EXPR(45695=0xb27f) ABS
pfciohobufinitstart = $b23d ; EXPR(45629=0xb23d) ABS
; END BNW CONSTANTS
VWLDASMSTARTVEC = $b0 ; Vector to beginning of space to disassemble
VWLDASMENDVEC = $b2 ; Vector to end of space to disassemble
VWLDASMCUROCVEC = $b4 ; Vector to the current "working" OpCode
DBLDASMOBWP = $ba ; Output Buffer Write Pointer (offset)
DBLDASMOBRP = $bb ; Output Buffer Read Pointer (offset)
DBLDASMOCVINCCNT = $bc ; Number of times to increment VWLDASMCUROCVEC
DBLDASMDONEFLG = $bd ; Done Flag -- Anything other than $00 means done
DBLDASOCWRKCPY = $be ; Working copy of the current OpCode
DBBTHSRC = $21
;DWBTHRES = $22
DWBTHRES = $72
PFBYTETOASCII = $e14f
;BTHRESL EXPR(115=0x73) EQU
;BTHRESH EXPR(114=0x72) EQU
.org $1000
pfbdasmentry:
;;;; Tell the CLCD we're streaking
lda #<$c200 ; dfr65msg001 ; $c200 ; dfr65msg001
sta $0090 ; VWMSGSYS ; $0090 ; VWMSGSYS
lda #>$c200 ; dfr65msg001 ; $c200 ; dfr65msg001
sta $0090 + 1 ; VWMSGSYS + 1 ; $0090 + 1 ; VWMSGSYS + 1
lda #pfbdasmclcdmsg ; twmesg ;;;; <<<======LOCAL MESSAGE
sta $0092 + 1 ; VWMSGPRG + 1 ; $0092 + 1 ; VWMSGPRG + 1
jsr $ce17 ; pflcd162spmsgtobufstart ; $ce17 ; pflcd162spmsgtobufstart
jsr $bd00 ; pfclcd162l1bufstart ; $bd00 ; pfclcd162l1bufstart
;; INITIALIZE THE THINGS
lda #$00
sta DBLDASMDONEFLG
clc
lda VWLDASMSTARTVEC
sta VWLDASMCUROCVEC
lda VWLDASMSTARTVEC + 1
sta VWLDASMCUROCVEC + 1
jsr pfbdasmserportinit
;;;; HERE BEGINS THE BIG OUTER LOOP
pfbdasmmainlooptop:
;; Save a working copy of the current OpCode
ldy #$00 ; Copy the Current OC Vector to "Working Copy"
lda (VWLDASMCUROCVEC),y
sta DBLDASOCWRKCPY
; Initialize the things
lda #$00
sta DBLDASMOBWP ; Output Buffer Write Pointer (offset)
sta DBLDASMOBRP ; Output Buffer Read Pointer (offset)
; Clear the Output Buffer
jsr pfciohobufinitstart
; Call the POC Disassembler
jsr pfpocdasmentry
; Write the Serial Buffer out to the port
jsr pfbdasmserportwrite
;;; Increment the "Current OpCode Vector" the correct number of
;;; times for the "length" of the OpCode
jsr pfbdasmcurocvecincstart
lda DBLDASMDONEFLG ; Get the "DONE" flag
cmp #$00 ; $00 == Keep going
bne pfbdasmexit ; Bail out if != 0
jmp pfbdasmmainlooptop
pfbdasmexit:
rts
;;;;;; INITIALIZE THE SERIAL PORT
pfbdasmserportinit:
; preserve the registers
pha
txa
pha
tya
pha
; Initialize the SIO4 device
;; Set baud rate write delay
lda #$08
sta CBSERBRDM ; CBSERBRDM
;; Set terminate character
lda #$00
sta DBCPBTERM ; DBCPBTERM
;lda #$04 ;;;
lda #$05
jsr pfsetcurpstart
lda #$10
jsr pfciohstdentry
;restore the registers
pla
tay
pla
tax
pla
rts
;;;;;; WRITE TO THE SERIAL PORT
pfbdasmserportwrite:
;;;; START WRITE TO SERIAL PORT MAYBE
; Preserve the registers
pha
tya
pha
txa
pha
;lda #$04 ;;;;
lda #$05
jsr pfsetcurpstart
lda #$62
jsr pfciohstdentry
;;;; END WRITE TO SERIAL PORT MAYBE
; Restore the registers
pla
tax
pla
tay
pla
rts
;;;;;;;;NEW INCREMENT CURRENT OPCODE VECTOR
pfbdasmcurocvecincstart:
pha
txa
pha
tya
pha
ldy DBLDASOCWRKCPY
lda dfopcdarglut,y
sta DBUTIL3 ; TMP copy of OpCode length
; Get the c lsb
lda VWLDASMCUROCVEC
; eor with $ff to see how many steps til carry
eor #$ff
sta DBUTIL4 ; tmp holding spot for "steps til carry"
lda DBUTIL4
cmp DBUTIL3 ; compare with opcode length
bcs pfbdasmcurocvecincinclsbonly ; no carry expected
lda DBUTIL3 ; Opcode Length
sbc DBUTIL4 ; tmp holding spot for "steps til carry"
sta VWLDASMCUROCVEC
clc
lda VWLDASMCUROCVEC + 1
adc #$01
sta VWLDASMCUROCVEC + 1
jmp pfbdasmcurocvecinccheckgt
nop
pfbdasmcurocvecincinclsbonly:
clc
lda VWLDASMCUROCVEC
adc DBUTIL3
sta VWLDASMCUROCVEC
nop
pfbdasmcurocvecinccheckgt:
lda VWLDASMCUROCVEC + 1 ; 80
cmp VWLDASMENDVEC + 1 ; 80
beq pfbdasmcurocvecincchecklsbgt
bmi pfbdasmcurocvecincdonedone
bpl pfbdasmcurocvecincoverflow
pfbdasmcurocvecincchecklsbgt:
lda VWLDASMCUROCVEC
cmp VWLDASMENDVEC
bmi pfbdasmcurocvecincdonedone
nop
pfbdasmcurocvecincoverflow:
lda #$ff
sta DBLDASMDONEFLG
nop
pfbdasmcurocvecincdonedone:
pla
tay
pla
tax
pla
rts
nop
nop
nop
nop
;;;;;;;;;;END NEW INCREMENT CURRENT OPCODE VECTOR
;;;;;;; START "PROOF OF CONCEPT" DISASSEMBLER
;.org $1800
pfpocdasmentry:
; Preserve the registers
pha
txa
pha
tya
pha
ldy #$00
lda (VWLDASMCUROCVEC),y ; Load the OpCode at the "Current OpCode Vector"
sta $0600 ; Store the OpCode in $0600
tay ; Move the OpcCode to rY
lda dfopcdmnemlut,y ; Load the Mnemonic Offset from the lookup table
sta $0601 ; Store the Mnemonic Offset in $0601
lda dfopcdarglut,y ; Load the Arg Count from the lookup table
sta $0602 ; Store the Arg Count in $0602
lda #$00 ; Set the "Working Arg" to #$00
sta $0603 ; Store the "Working Arg" to $0603
lda #$00
sta $0604 ; Out Buff Offset
;; We're going to put an output string in RAM, starting at $06010
;; First, post the current address
lda VWLDASMCUROCVEC + 1
jsr PFBYTETOASCII
lda DWBTHRES ; 72
jsr pfciohobufappendbytestart
lda DWBTHRES + 1 ; 73
jsr pfciohobufappendbytestart
lda VWLDASMCUROCVEC + 0
jsr PFBYTETOASCII
lda DWBTHRES ; 72
jsr pfciohobufappendbytestart
lda DWBTHRES + 1 ; 73
jsr pfciohobufappendbytestart
lda #$3a ; ":"
jsr pfciohobufappendbytestart
lda #$20 ; " "
jsr pfciohobufappendbytestart
;; Second, copy the Nmemonic
lda $0601
tay
lda dfmnemreflut,y
jsr pfciohobufappendbytestart
iny
lda dfmnemreflut,y
jsr pfciohobufappendbytestart
iny
lda dfmnemreflut,y
jsr pfciohobufappendbytestart
;;
;; We would put a decoration here if appropriate
;;
;; Add a space
lda #$20
jsr pfciohobufappendbytestart
;;
;; Convert the OpCode to ASCII Hex
ldy #$00
lda (VWLDASMCUROCVEC),y
sta DBBTHSRC
jsr PFBYTETOASCII
lda DWBTHRES ; 72
jsr pfciohobufappendbytestart
lda DWBTHRES + 1 ; 73
jsr pfciohobufappendbytestart
;;
;; Add a space
lda #$20
jsr pfciohobufappendbytestart
ldy #$01
pfpocdasmarglooptop:
cpy $0602 ; If we're already at the "length" value, dump out.
beq pfpocdasmdone
;; FIRST ARG
lda (VWLDASMCUROCVEC),y
sta DBBTHSRC
jsr PFBYTETOASCII
lda DWBTHRES ; 72
jsr pfciohobufappendbytestart
lda DWBTHRES + 1 ; 73
jsr pfciohobufappendbytestart
lda #$20
jsr pfciohobufappendbytestart
;; SECOND ARG
iny
cpy $0602 ; If we're already at the "length" value, dump out.
beq pfpocdasmdone
lda (VWLDASMCUROCVEC),y
sta DBBTHSRC
jsr PFBYTETOASCII
lda DWBTHRES ; 72
jsr pfciohobufappendbytestart
lda DWBTHRES + 1 ; 73
jsr pfciohobufappendbytestart
lda #$20
jsr pfciohobufappendbytestart
;; THIRD ARG
iny
cpy $0602 ; If we're already at the "length" value, dump out.
beq pfpocdasmdone
lda (VWLDASMCUROCVEC),y
sta DBBTHSRC
jsr PFBYTETOASCII
lda DWBTHRES ; 72
jsr pfciohobufappendbytestart
lda DWBTHRES + 1 ; 73
jsr pfciohobufappendbytestart
lda #$20
jsr pfciohobufappendbytestart
pfpocdasmdone:
lda #$0d
jsr pfciohobufappendbytestart
lda #$0a
jsr pfciohobufappendbytestart
lda #$00
jsr pfciohobufappendbytestart
lda #$ea
jsr pfciohobufappendbytestart
; Restore the registers
pla
tay
pla
tax
pla
rts
;;;;;;; END "PROOF OF CONCEPT" DISASSEMBLER
pfbdasmclcdmsg:
;.asciiz "P: R65 DisASM"
.asciiz "P: R65 CrapDASM"
.byte $00,$00,$00,$00, $00,$00,$00,$00, $00,$00,$00,$00, $00,$00,$00,$00
.asciiz "DEADBEEFdeadbeef"
; Lookup Tabels:
; Opcode to Mnemonic Lookup (dfopcdmnemlut)
; Opcode to Arg Count Lookup
; Mnemonic Reference (dfmnemreflut)
.org $2000
;;;;; MNEMONIC BY OPCODE LOOKUP TABLE
; OpCodes are one byte each.
; OpCode is offset from start of table
; Value at offset is offset from start of dfmnemreflut containinf the Mnemonic
dfopcdmnemlut:
.byte $30,$84,$f0,$f0,$f0,$84,$08,$f0,$d0,$84,$08,$f0,$f0,$84,$08,$f0
.byte $10,$84,$f0,$f0,$f0,$84,$08,$f0,$48,$84,$f0,$f0,$f0,$84,$08,$f0
.byte $6c,$04,$f0,$f0,$0c,$04,$a8,$f0,$d4,$04,$a8,$f0,$0c,$04,$a8,$f0
.byte $f0,$04,$f0,$f0,$f0,$04,$a8,$f0,$4c,$04,$f0,$f0,$f0,$04,$a8,$f0
.byte $b0,$44,$f0,$f0,$f0,$44,$7c,$f0,$c8,$44,$7c,$f0,$68,$44,$7c,$f0
.byte $18,$44,$f0,$f0,$f0,$44,$7c,$f0,$50,$44,$f0,$f0,$f0,$44,$7c,$f0
.byte $b4,$00,$f0,$f0,$f0,$00,$ac,$f0,$cc,$00,$ac,$f0,$68,$00,$ac,$f0
.byte $1c,$00,$f0,$f0,$f0,$00,$ac,$f0,$54,$00,$f0,$f0,$f0,$00,$ac,$f0
.byte $f0,$bc,$f0,$f0,$dc,$bc,$d8,$f0,$a0,$f0,$8c,$f0,$dc,$bc,$d8,$f0
.byte $20,$bc,$f0,$f0,$dc,$bc,$d8,$f0,$9c,$bc,$c0,$f0,$f0,$bc,$f0,$f0
.byte $78,$70,$74,$f0,$78,$70,$74,$f0,$98,$70,$88,$f0,$78,$70,$74,$f0
.byte $24,$70,$f0,$f0,$78,$70,$74,$f0,$58,$f0,$c4,$f0,$78,$70,$74,$f0
.byte $3c,$34,$f0,$f0,$3c,$34,$40,$f0,$a4,$34,$90,$f0,$f0,$34,$40,$f0
.byte $28,$34,$f0,$f0,$f0,$34,$40,$f0,$5c,$34,$f0,$f0,$f0,$34,$40,$f0
.byte $38,$b8,$f0,$f0,$38,$b8,$64,$f0,$94,$b8,$80,$f0,$f0,$b8,$64,$f0
.byte $2c,$b8,$f0,$f0,$f0,$b8,$64,$f0,$60,$b8,$f0,$f0,$f0,$b8,$64,$f0
;;;;; ARGUMENT COUNT BY OPCODE LOOKUP TABLE
; OpCodes are one byte each.
; OpCode is offset from start of table
; Value at offset is number of additional bytes to read for this OpCode
dfopcdarglut:
.byte $01,$02,$00,$00,$00,$02,$02,$00,$01,$02,$01,$00,$00,$03,$03,$00
.byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
.byte $03,$02,$00,$00,$02,$03,$02,$00,$01,$02,$01,$00,$03,$03,$03,$00
.byte $00,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
.byte $01,$02,$00,$00,$00,$02,$02,$00,$01,$02,$01,$00,$03,$04,$03,$00
.byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
.byte $01,$02,$00,$00,$00,$02,$02,$00,$01,$02,$01,$00,$03,$03,$03,$00
.byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
.byte $00,$02,$00,$00,$02,$02,$02,$00,$01,$00,$01,$00,$03,$03,$03,$00
.byte $02,$02,$00,$00,$02,$02,$02,$00,$01,$03,$01,$00,$00,$03,$00,$00
.byte $02,$02,$02,$00,$02,$02,$02,$00,$01,$02,$01,$00,$03,$03,$03,$00
.byte $02,$02,$00,$00,$02,$02,$02,$00,$01,$00,$01,$00,$03,$03,$03,$00
.byte $02,$02,$00,$00,$02,$03,$02,$00,$01,$02,$01,$00,$00,$03,$03,$00
.byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$04,$00
.byte $02,$02,$00,$00,$02,$02,$02,$00,$01,$02,$01,$00,$00,$03,$03,$00
.byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
;;;;; MNEMONIC TEXT LOOKUP TABLE
; Mnemonics are all 4 bytes long - 3 character and a NUL ($00) terminator
dfmnemreflut:
.byte $41,$44,$43,$00,$41,$4e,$44,$00,$41,$53,$4c,$00,$42,$49,$54,$00
.byte $42,$50,$4c,$00,$42,$4d,$49,$00,$42,$56,$43,$00,$42,$56,$53,$00
.byte $42,$43,$43,$00,$42,$43,$53,$00,$42,$4e,$45,$00,$42,$45,$51,$00
.byte $42,$52,$4b,$00,$43,$4d,$50,$00,$43,$50,$58,$00,$43,$50,$59,$00
.byte $44,$45,$43,$00,$45,$4f,$52,$00,$43,$4c,$43,$00,$53,$45,$43,$00
.byte $43,$4c,$49,$00,$53,$45,$49,$00,$43,$4c,$56,$00,$43,$4c,$44,$00
.byte $53,$45,$44,$00,$49,$4e,$43,$00,$4a,$4d,$50,$00,$4a,$53,$52,$00
.byte $4c,$44,$41,$00,$4c,$44,$58,$00,$4c,$44,$59,$00,$4c,$53,$52,$00
.byte $4e,$4f,$50,$00,$4f,$52,$41,$00,$54,$41,$58,$00,$54,$58,$41,$00
.byte $44,$45,$58,$00,$49,$4e,$58,$00,$54,$41,$59,$00,$54,$59,$41,$00
.byte $44,$45,$59,$00,$49,$4e,$59,$00,$52,$4f,$4c,$00,$52,$4f,$52,$00
.byte $52,$54,$49,$00,$52,$54,$53,$00,$53,$42,$43,$00,$53,$54,$41,$00
.byte $54,$58,$53,$00,$54,$53,$58,$00,$50,$48,$41,$00,$50,$4c,$41,$00
.byte $50,$48,$50,$00,$50,$4c,$50,$00,$53,$54,$58,$00,$53,$54,$59,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $3f,$3f,$3f,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
...and that's all I have to say about that.