Sunday, December 26, 2021

Tools!

Tools!

Getting started in hobby electronics is a lot easier today than it was 30 years ago.  Back then, you were lucky if you had a decent electronics shop within an hour's drive, and even then, the on-hand stock of parts and tools was likely a mere sprinkling of what was really out there.  If you weren't already in the business, or fortunate enough to live near a tech-heavy area like Boston or Silicon Valley you had to depend on magazine ads and scant occasional word of mouth to have any idea what lay beyond one's own confining horizon.

Today, we're spoiled for choice.   The Open Source movement has breathed new life into "technology as a hobby".   The Internet has brought both the world of commerce, and of information right to your desk. Advances in semiconductor manufacturing, miniaturization, and yields have brought about unprecedented declines in cost-per-transistor and increases in transistors-per-square-millimeter.  Economies of scale have made what, back in the day, we would have called "electronics surplus" an industry unto itself.

Here are some of the tools I use while working on the RIBBBIT65 (none of these are affiliate or sponsored links):

Thursday, December 16, 2021

"Science Journalism" -- a rant.

It's sentences like this, 'This includes innards like logic circuitry, which enable your computer to make complex non-binary decisions like “or,” “and,” or “if only” instead of simply “yes” or “no”.' in this superficially interesting article  that just immediately cause me to hate the article, be deeply disappointed by the author, and just want humanity to finish dying already.

I hate the article because it contains the construct.  "or" and "and" are boolean operators... yes, they are expressly, definitionally binary.  "if only" ... I don't know what to do with this.  Is there a circuit that makes a computer engage in wistful speculation?  This is one of those things that brings the whole house of cards down for me.  How can I trust anything in this article, which required actual effort to research, when it gets something so basic, clearly defined, and easily verifiable, wrong?  

I am deeply disappointed by the author because a) She took an interesting historical topic relating to technology and sacrificed it in the volcanic caldera of the Lowest Common Denominator; b) In pandering to a non-technical audience, she got the technical bits wrong, and in so doing, planted the seeds of misconception in the minds of her "don't know better" audience members; and c) she is an award-winning "science journalist" and should know better -- according to her Bio page on Inverse , 'Sarah earned her M.S. in science journalism from Boston University in 2018 and was awarded SciShortForm's "Top Pick" blog and honorable mention in 2019. She is also a member of the National Association of Science Writers.'  MASTERS OF SCIENCE IN SCIENCE JOURNALISM from BOSTON UNIVERSITY.  Just hold that turd in your mouth for a couple minutes... let the flavors develop.  Remember, kids:  You never get a second chance to make a first impression.

I just want humanity to finish dying already because we're over 40 years into the "personal computer revolution" (to say nothing of the 70-ish years since general purpose programmable computers became a practical "thing") and "popular press" audiences still need fundamental logic explained to them in a manner akin to "when a mommy and a daddy love each other very much, they do a special hug that makes a baby", and the popular press delivers it like, "all hugs make babies special mommies and daddies."  How is this a thing?  We've had 2 generations to inculcate children with a basic understanding of what the difference between "and" and "or" is.  Nope.  Let's buy new football uniforms, instead.  

I understand the "cool" thing in journalism is being dispassionate... well you need to be passionate about one thing:  not saying wrong things.  ...and the audience cares enough, maybe, to read the article, but not enough to stop at a bit that makes no sense, or seems to contradict itself, and check elsewhere.  That's probably the only exposure a lay audience member is going to get to some inkling of what a logic gate is, and now that lay audience member "understands" it wrong, instead of not knowing.  Do you want Trump for President?  Because this is how you get Trump for President.


Wednesday, December 15, 2021

CrapDASM Demo (et al) Video!

Just posted a new video to the YouTube channel -- Mostly covers the CrapDASM disassembler.  



One thing I didn't mention (because I forgot in the moment) among the things I want to fix/improve on the CrapDASM (and, yeah, I think that's going to be the name) is "decorations" for the mnemonics.  For example,  indicating vectors, indexed offsets, and stuff like that.  Right now, you can't just take the disassembler output, type it into an assembler, and go...  and while that may never actually be a thing, I'd like to get a little closer to understanding what's going on by reading the disassembler output.  Decorations are distinct based on opcode, and there is a finite and small list of decorations (basically one for each addressing mode).  

I also discovered (after posting the video) and issue with the routine that increments the the vector to the current OpCode.  Moar debugging!

Anyway,  progress is being made, so, hooray!

Sunday, December 12, 2021

Avengers! Disassemble!

 

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.

Thursday, December 9, 2021

Updates, Distractions, and Failures

 Updates, Distractions, and Failures

I dropped my phone over the last weekend and spidered the screen.  That was a disappointing failure.  New phone should be arriving today.  Apologies for the potato photos that follow.

PCB Update

I put in an order for 4 new boards weekend before last, and they showed up this past Tuesday, which was cool.  In that order were:

  • COREplus r0.2
  • SystemIO r0.2
  • ITX CORE Daughter Card (a.k.a. the CORE Mezzanine) r0.1
  • ATX Power Adapter/Switcher r0.1

New boards!

All the boards arrived, and appear to be manufactured as designed.  That's good.  Thanks, JLCPCB!

I assembled one of the COREplus r0.2 boards, and it works.  Power-on Reset works without bodges, and the blinkenlights work.  So, that's good.

COREplus r0.2 - BLINKENLIGHTS!

I did some continuity checks on the SystemIO r0.2, and it turns out I messed that up.  The silkscreen issue with the "future peripherals" headers has been resolved, which is great, but it looks like I messed up on the RS-232 fixes, so all 5 ports still have the reveresed TXD and RXD lines between the MAX232s and the respective DB9 connectors.  I DID fix the problem in the schematic, but, apparently, I got distracted and never updated the PCB in KiCAD.  That has been remedied, and so, in r0.3, there should be no bodges required (for that, at least).  A mistake I hope never to make again.

I assembled one of the ITX CORE Daughter Card r0.1 boards, and it appears to be working-ish... the CPU, RAM, and ROM are all appearing to do stuff.  ...that is, once I put the clock oscillator in the right way (after cooking 3 of them -- not my proudest moment).  Unfortunately, hooking up a Jenny-O with the 6551 daughter card is, so far, not yielding communication.  I'm investigating.

ITX CORE Daughter Card r0.1 - Can it be saved?

I have not yet assembled the ATX Power Adapter/Switcher r0.1.  Might get stuck in to that this week.  It is not my highest priority at the moment.

CoreROM update

I've been working on a disassembler for inclusion in the CoreROM.  The way it would work is you put a start address and an end address in some special spot in RAM, and it will pick out the opcodes, match them to the mnemonics, recognize how many arguments that opcode should have, see if there's any "decoration" (like ",Y" or ",X" or " A"), and display the mnemonic, the decoration (if any), the opcode and the arguments (if any).  This has been slow going.  Putting together the lookup tables to get the opcodes and argument counts manually was a total pain, and I think I messed it up.  I went back to the drawing board, and wrote a Python tool to build the lookup tables.  That seems to have worked a treat, but I think I'm having a problem with a subroutine call maybe nuking a register somewhere along the way.  Debugging continues.

RIBBBIT65 ITX update

As I was poking around on DigiKey and Mouser, I found IO connectors I think I'm going to use, which is good.  I'm looking at double-stacked DB9Fs for the general purpose RS-232s, a single DB9M for the console, and double-stacked DB25Fs for the 2 general purpose VIAs.  While I was on Mouser's site, I discovered that they sell WDC's product line -- like the whole thing, apparently.  Looks like they have the W65C02, W65C22, and W65C51 in PLCC.  I poked around a little more, and discovered that, even in THT sockets, they are quite a bit smaller than the DIP40s and DIP28s I've been using so far.  I can fit almost 3 PLCC44s in the space of one DIP40 (in terms of board real estate).  If I go that route for the WDC chips and the EEPROMs, and SMT for the MAX323s and RAM, I might be able to fit the CORE and SystemIO on one MiniITX board.  It will certainly be more expensive than using dual-wipe sockets on DIP chips as I have been so far, but in a Mini-ITX form factor, that might be excusable.  I'd probably have to do a mezzanine card for the "Pageable ROM" and maybe a 3.5" External Bay thingy (prolly 3D printed) for the Cartridge Slot as options, but that's still pretty cool.  I'd be curious to hear your thoughts.

So, as of early December, that's where we are.


Sunday, December 5, 2021

RIBBBIT65: Why Is?

RIBBBIT65: Why Is?

The RIBBBIT65_COREplus

First and foremost, the RIBBBIT65 is an autodidactic exercise, wherein I learn how computers work at the "machine language and bus signal" level.

You see, I was at just about the right age to be in the target demographic when home computers started taking off -- the late '70s, early '80s.  It was really neat.  A friend of mine who was very, very smart, and was fortunate enough to have positive and encouraging parents, got a computer... I think it was for Christmas... an Atari 400.  ...and I was *fascinated*.  He got really, really good with the programming... so much so that he'd started not just writing little machine language subroutines that he'd call from BASIC... no.  He got an Assembler/Editor cartridge and was writing whole programs in Assembly.  At this point I had no computer.  I would shoulder surf and he'd show me programs he'd written in BASIC, and I could kinda make sense of them.  I could *get* BASIC.  I could probably make a computer do things.  

Well, another Christmas, another computer.  I don't recall if it was the *next* Christmas, but it wasn't long after the Atari 400 hundred showed up, that his parents had gotten him an Atari 800 (With a floppy drive!) as an upgrade, since he'd outgrown the 400.  I mean, fine... anyone could outgrow 16K or RAM... but 48K?  I'd like to see you try.  Well, his 400 found its way to the basement of their house and stayed there for a while.  

At this time, I was more or less a fixture at their house (I was more ubiquitous than the paint on the walls), and we would often play in their basement (because... outside?  what's that?!).  On the way down and on the way up, I would see that Atari 400 sitting there... unused.  Lonely.  Finally, I got up the nerve (and scraped together a little cash) and asked my friend's dad if I could buy the old 400...with its cassette drive.  $30 later, it was mine.  

Soon, I was writing BASIC like a banshee.... I guess.  I don't know much about banshees.  Anyway, I was printing, "Hello world" on the screen and flashing colors and doing all sorts of basic stuff.  It was neat.  ...but there was something about sprites and machine language that made them.... beyond me... somehow.  Maybe it was the fact that Atari BASIC supported them, kinda, but I didn't really get a good idea of the how of it.  I don't know if it was a cognitive thing or a psychological thing... but my young thinkymeat was having none of it.

Time and a half went by, and I'd upgraded my rig to an Atari 800XL with a floppy drive, and I was doing some cool stuff with that, but I never really got into Assembly.  Eventually, I made the leap into PCs.  That was 1991, and I've been getting farther and farther from the bare metal ever since.

In the intervening years, I've actually settled into a career in IT.  I've become a Linux nerd.  I've picked up several languages, but in the back of my mind, there was a little bugaboo; a tiny voice in the dark, telling me I didn't really get it.  ...not really.  It was that sad little 400 in the basement.

In 2016, not long after starting a job with a 3-hour round-trip commute by rail, I decided I would undertake a project to "get" machine language.  I decided I would write a CPU emulator.  Strictly speaking, it ended up being more of a "machine language interpreter"... but, it worked.  I wrote a monitor program (in bare Z80 machine language... not Assembly.... the actual opcodes) that was a little under 2K.  Why yes, the train was a terrible soul-crushing thing.

I got a couple "retro computer" type kits, and they were neat, but there was always something lurking in the background.... telling me I didn't really get it.  ...not really.  Most of these machines, like the RC2014, are kinda limited in scope, and while others have done cool expansions to them, I was hitting a roadblock.  The "working" part of the system was a sort of barrier.  For fear of breaking what worked, I didn't dare muck about.

Then, in 2020, I caught wind of Ben Eater's excellent series of videos about building a 6502-based computer from the ground, up.  Like Sir Robin at the Bridge of Death, after seeing Galahad's triumph, I thought, "This is something I could do."  I ordered Ben's 6502 kit, and got cracking.  I was having some trouble keeping all the wiring straight on the breadboards, and I was getting frustrated... I didn't know whether the problem was my wiring, the breadboards, or faulty parts.  From a number of sources, I'd become aware that there was a decent Open Source "Electronic Design Aid" -- KiCAD, and there were board houses out there that could do low-cost prototype manufacturing... so I put ham and cheese together, and went about re-implementing Ben Eater's design in KiCAD, and getting some boards made.  After finding and fixing the error I'd made on the board (there's always one, isn't there?), it was great.  I could actually do things.  I could write programs in Assembly, burn them to an EEPROM, and they'd actually work.

At this point, I'd arrived at the same sort of frustrating point I was at with the "retro computer" kits.  If I was going to move forward, I'd have to take the risk of wrecking it.  But, there was one significant difference.  I had made everything that worked, and I had spares.

I was finally free to think creatively and solve problems (which, I readily admit, had been solved countless times before, far more elegantly, by numberless people).  Like so many other projects which had engaged and held my interest, I had a basic set of essentially indestructible tools, a practically limitless supply of resources, and only the laws of physics to constrain me.  I could play.  I could try things out.  I could fail.  

So, I thought about the itches that needed scratching.

One thing that bothered me about the commercially-available "home computers" was that they were kind of closed black boxes.  Between FCC regulations, product safety regulations, building down to a cost, and various other pressures, machines like the Atari 8-bits, and the Commodores were kind of closed off and inaccessible to me.  Here's your feature set.  Like it.  The Apple ][ seemed more open, but was obscenely expensive, and, therefore, off-limits.  Many of the retro kits were even more constrained.

I wanted a lab computer.  Something I could pull apart and rejigger as I saw fit, to serve whatever purpose I had in the moment.  I wanted a machine that would afford me a lot of IO possibilities, because who knows what I might want to do with it?  Something like one of those old Radio Shack "hundred and one electronic projects" kits, but not lame.  I decided it should have a good, broad set of base peripherals - A console, some serial ports, a couple VIAs, I2C and SPI, storage, so that you could stand up a really usable computer... or pare it back if need be, to save space or power, or whatever. I also thought it should have some expand ability so an end user could put in whatever they want.

I wanted to go through the process of building up an operating system.  What kind of masochist would subject himself to such a thing?  This kind, apparently.  Device drivers, APIs and so on.  I wanted to build those things, so I could really understand what's going on under the hood.

People have asked me about graphics and sound and what games I want to be able to play on it.  For me, the goal is not to play games on the RIBBBIT65.  I have a Nintendo Switch Lite for that.  The RIBBBIT65 *is* the game.

So, today, the RIBBBIT65 is on its way.  I have a good, stable core machine, and an IO platform on which to build something useful.  I have a decent Monitor program, and I'm working on an IO handler to abstract the various underlying peripherals.  There are design aspects which folks have told me remind them of the BBC Micro, which I suppose is flattering, as that's a highly-regarded machine for its time.  

I have a plan to do a version of the RIBBBIT65 in a Mini-ITX form-factor to allow more "hands off" use of the machine, as well as unifying a "bench-top" version, where the guts are all accessible, but it mechanically fits together better than the boards I've done so far.

I'm thinking of doing a hand-held "pendant"-style console device for interacting with the R65 Monitor, with, say, a 24-key keyboard, and either a character LCD or 7-segment LEDs to show addresses and data bytes.  It would speak a stripped down dialect of the monitor command set (for example, "page dump" wouldn't really work on a 6-digit LED)

I'm not just building a computer, I'm finally building understanding.  The RIBBBIT65 is on the verge of being a mere byproduct... an artifact whose significance lies in the research and trial and error that bought me the understanding to build it in the first place.  This is far more satisfying than any work I've done for money in the last 20 years.  It's certainly not for everyone.  But it is for me.


RIBBBIT65: What Is It?

RIBBBIT65: What Is It?

There are a lot of ideas out there in the world about what a computer should be, and what a computer should be able to do.

Certainly a computer should be able to execute specified commands in a specified order, retrieve and store data, and be able to perform arithmetic and logical operations on that data.  It should be able to accept some input, and provide some output.  Its execution of instructions should be able to be altered either by data values or input received.

Beyond that, the intended application goes a long way toward dictating what the specifications and requirements are which will drive the design.

So, what is the RIBBBIT65, beyond being a computer?  What kind of computer is it?

The RIBBBIT65 is an 8-bit microcomputer, based around the Western Design Center's W65C02 microprocessor family.

It is intended primarily as general purpose computer with an eye on learning.

The computing ecosystem is radically different today than it was when the MOS 6502 was first introduced in 1975.  Today, our computers have so much spare horsepower, we can emulate whole computer systems in our web browsers.  Almost everybody who could read this post has a computer of some kind and access to the Internet.  Today, you really don't need "the actual hardware" to enjoy a completely reasonable emulation or simulation of using old hardware, if that's your interest.

I'm not going to lie, though.  There are some of us, for whom the simulation is insufficient.  Some of us want to poke pins with probes.  Some of us want to talk to the CPU on its own terms.  There are some times when the simulation and the emulation are not what is needed.  Sometimes you actually need the hardware.

There are people out there who have done amazing work, re-implementing Commodore, Sinclair, and Atari systems with blends of new and old hardware, and I applaud their efforts.  Reverse-engineering a VIC-II or an ANTIC can't be an easy task.  For me, though, with each ASIC and ULA there is a definition of borders and an imposition of constraints.  With every piece of "other people's software" between me and the CPU, the machine itself becomes more diffuse and meaningless.  

I wanted a chance to work down on the bare iron, and stand up a computer.  A system.  I wanted the feeling of discovery and triumph that came from wrangling a box of rattly parts and wires into a working machine with peripherals and a workable but simple interface.  Something that would allow me to demonstrate, tame, and use most of the core functionality from the dawn of the microcomputer age.  

I have mixed feelings about things like floppy disks and CRT monitors.  Aesthetically, I find them appealing.  I like the idea of them -- the close relationship between the abstract and the concrete... between ethereal electrical fluctuations and real, physical phenomena.  Functionally, I feel they were good for their time, but I have no practical use for them today.

I had struggled for a long time with the conceptual leap required for me to grok machine language.  Ben Eater's "Hello World From Scratch" video straightened most of that out for me.  I finally saw a path to the kind of machine that interested me.

What kind of machine is that?  It's the RIBBBIT65, of course.

The RIBBBIT65 is a general purpose computer.  It's not a games machine or an industrial controller -- not by design, anyway.  Initially, I just wanted to make a board that would give me a good base-line 6502-based system that I could experiment with, that only required that I knew the 6502 itself, the basic layout of the memory map (e.g. where RAM, ROM, and IO are).

RIBBBIT65_COREplus

The RIBBBIT65_COREplus board satisfies that need for me.  It's got all the basic functionality, and conforms to a fairly straightforward model - 32K ROM, 32K RAM.  You want to do more with it, you can hang stuff off the bus.

The RIBBBIT65 CoreROM is currently in development, but at this stage, it has a working monitor program, and a framework for an abstracted IO handler and interrupt handler.  The CoreROM is divided into 4 8K segments, with one (the lowest 8K segment) being set aside as ROM that can be paged-in and -out as needed.

The RIBBBIT65 ROMxpander is still in early stages of development, but the intent is to provide 3 32K user-installable ROMs (intended to changed infrequently) which are each broken up into 4 8K segments, which can be paged in for the lower 8K of the CoreROM.  One possible application would be one ROM chip would contain up to 4 programming languages or tools, while another might contain up to 4 productivity tools.  The ROMxpander is also planned to accept an 8K "ROM cartridge" with the ability to quickly and easily switch ROM-based programs.

RIBBBIT65 SystemIO

The RIBBBIT65 SystemIO board provides a set of peripherals and related functionality to let the RIBBBIT65 interact with the world.  It has a serial console, which nearly all modern "retro-computer" kits have, but it also has 4 additional general purpose RS232 ports.  It has 2 general purpose W65C22 Versatile Interface Adapters, and a third for driving an LCD character display.  There are plans for storage devices, SPI & I2C adapters, and an interrupt controller to allow multiple devices to send interrupts to the CPU (provided the software is setupt to handle them properly).  Space has also been set aside for a "character addressable video display adapter" on the SystemIO bus, which could allow something on the order of Sinclair ZX Spectrum graphics, full-screen editing, and so on.

The RIBBBIT65 UserIO board is, at this stage, mostly just conceptual, but it is intended to leverage the SystemIO board, and provide an additional 16 ports for user-defined peripherals, with interrupt handling for upto 7 of them.

Finally, the RIBBBIT65-ITX (in development) is intended to provide a subset of RIBBBIT65 functionality in a Mini-ITX form factor to permit use in a variety of applications and settings, in an enclosure of the user's choosing, and connecting to industry standard ATX power and front-panel connections.

A New Start -- And A Return

Hi.

I'm Paul, a 50-something nerd. I've been noodling with computers in one way or another since the early 1980s. With the proliferation of "retrocomputing chic" out there, I thought I'd dip my toe in the field.

This is RIBBBITN3RDing

This is a particularly great time to get into "primitive computing", as the availability of parts, resources, and services is, for the most part, fantastic. Sure, there are specific parts for old Atari and Commodore machines that are no longer being manufactured -- but some of them have been reverse-engineered and created in CPLDs or other programmable devices.

Companies like Adafruit, Jameco, DigiKey, Mouser, and the like make parts available to ordinary folks like you and me. There're great, low-cost tools out there, from solder stations to oscilloscopes and logic analyzers, to make getting into this hobby a lot more straightforward than it was 20 years ago. Even Amazon has a lot of tools and parts for electronics hobbyists.

As if the availability of tools and parts was not enough, the availability of great information relating to retrocomputing both through "old fashioned" forums and static web pages, and though platforms like YouTube and Facebook is almost too much.

Of course, there are plenty of people who already knew this, and have been involved in the hobby for years, or decades. Thankfully, most of them are welcoming to new people in my experience, and har happy to give advice and answer questions.

My current project in this realm is the "RIBBBIT65" -- a 6502-based computer I was inspired to begin designing and building after watching these videos by Ben Eater. The RIBBBIT65 grew out of my desire to have a stable "core" that I could build on to develop peripherals and software. The project is ongoing, and I plan to document the stages of development, design choices, and lessons learned on this blog. I also have a YouTube channel where I post demos of nerdy stuff I'm working on (including RIBBBT65 stuff). I've already been working on the RIBBBIT65 for about a year and a half, so if you're feeling a little late to the party, I'm sorry. I'll try to get you caught up. This is an ongoing journey. I hope you join me, and we can learn together.

RMVOD r0.9.3 is here!

 Hi folks!   Well, TV Series Playlists are here, as well as some fixes to Recommendations.  Here are the release notes: RIBBBITmedia Video O...