Wednesday, August 26, 2020

Article: Understanding Quake's Fast Inverse Square Root

This article pretty much confirms what I suspected, but the author explains it pretty well.
The only thing really missing is how the "magic number" was derived to minimize the error.
This is just speculation on my part, but I see two potential approaches.
The first would be to pick some mid point value that reduces the maximum error for any legal number (within the range of floating point numbers).
The second would be to pick a value that is the mid point for the most common values a program uses, thus minimizing the error for that program more than for any value.
The first would be easy to calculate, the 2nd would require a lot of number logging & crunching.
https://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/ 


Monday, March 9, 2020

A little blast from my past

Back in the 80s I was a partner in and vice president of a software business called Designing Minds, Inc.
Here are a few of the programs we produced.  All of these are based on my runtime library, as was the Talking Storybook series, yet I somehow didn't get my name on any of the Copyrights.  Gee, why did I ever leave?
Link


I was also president, and a partner in an Amiga hardware company.
Here is one of the Amiga drives we made:
Link

Monday, March 2, 2020

MC-10 Memory map

This is the MC-10 memory map copied from the service manual, but with a few minor changes.
The address decoding inside the MC-10 is "minimal", so the Keyboard/VDG I/O responds over a full 16K area, but internal address decoding can be disabled by external expansion devices.
Programmer's should only use the top of that address range to access that hardware.

The MC-10 only includes 4K of RAM internally, but hi-res 256x192 2 color (RG6), and 128x192 4 color (CG6) modes require 6K.  The 6847 VDG's buss is isolated from the expansion connector on the back of the machine, and the top address line isn't even connected, so you can't just plug in a RAM expansion to use hi-res modes.  The hardware mod was published in a CoCo magazine shortly after the machine was released, but I'll have to look up what magazine.  (Color Computer Magazine maybe?)

Making matters worse, the ROM places BASIC system variables, and interrupt vectors in the upper part of the internal 4K of RAM, so to use hi-res graphics you need a new BASIC, or to disable the ROMs.  I've been working on a new ROM, so this is trivial for emulators.



MC-10 Memory map from the service manual
Hex Address
C000 - FFFF            16K ROM (only upper 8K used)
9000 - BFFF            16K I/O Slot (Keyboard, VDG control, and sound)
4000 - 8FFF            16K RAM (4K - 20K used) (video starts at $4000)
0100 - 3FFF            Not Used
0080 - 00FF            RAM internal to the 6803
0015 - 007F            Not Used
0014                RAM Control Register
0013                Not Used
0012                Not Used
0011                Not Used
0010                Not Used
000F                Port 3 Control and Status Register
000E                Input Capture Register (low byte)
000D                Input Capture Register (high byte)
000C                Output Compare Register (low byte)
000B                Output Compare Register (high byte)
000A                Counter (low byte)
0009                Counter (high byte)
0008                Timer Control and Status Register
0007                Not Used
0006                Not Used
0005                Not Used
0004                Not Used
0003                Miscellaneous I/O Data Register
0002                Keyboard Output Lines
0001                Data Direction Register for miscellaneous I/O
0000                Data Direction Register for keyboard lines

Nearing completion of the 6502 to 6803 AGD runtime code

As the title indicates, the runtime library code is almost complete.  If I had just focused on working on the translation, this would have been done some time ago. but I hope to finish this today.  Then I can look at the compiler.

There are some questions with the code that will require looking at the original Z80 code.  Why did they do this, why didn't they do that... not sure if the 6502 programmer lacked experience, if I have outdated code, or whatever, there's just some odd looking stuff in the code. 

There are sure to be some mistakes in the translation.   At the very least, the Z80 & 6502 store 16 bit variables in little endian format, and the 6803 uses big endian.  I'm assuming big endian for the translation, which may cause some problems.  There may also be a few times where I tried to optimize the code, and I shouldn't have.  Likewise, there's probably room for more optimizations where I wasn't sure if they are okay.

Before anyone gets too excited, just remember this requires the internal RAM mod that lets you use hi-res RG6 mode (PMODE 4), and a new ROM or external RAM expansion that lets you disable the internal ROM.  The only RAM expansion that lets you disable the ROM is the MCX-128, but I'm not sure that has a memory map setting compatible with the internal RAM upgrade.  This should work with an emulator though, and we can worry about the hardware issues later.

Saturday, February 29, 2020

code update

The egregious 6502 vs 6803 code comparison has been updated.  Yup, I was tired.  The 6803 code should be okay now.  While fixing the 6803 code, I also noticed the 6502 code looked like it could be improved.

The 6502 code from the shrapnel routine looks like it can be optimized as shown below.  Instead of incrementing z80_hl for every byte, use different y offsets, and then update z80_hl once.  The comparison is a little less lopsided with this change.

;----------------------------------------------------
; Explosion shrapnel.
;----------------------------------------------------

shrap:
    ldy #1
    lda (z80_ix),y         ; get the angle.
    clc
    adc #<shrsin        ; shrapnel sine table.
    sta z80_l
    lda #>shrsin
    adc #0
    sta z80_h

    ldy #0
    lda (z80_hl),y         ; fetch value from table.
    sta z80_e

    iny          ;#1
    lda (z80_hl),y        ; fetch value from table.
    sta z80_d

    iny          ;#2
    lda (z80_hl),y         ; fetch value from table.
    sta z80_c

    iny          ;#3
    lda (z80_hl),y         ; fetch value from table.
    sta z80_b


    lda    z80_l            ; add 4 to hl to advance pointer
    clc
    adc    #4

    sta    z80_l
    bcc    :+
    inc    z80_h
:


    ldy  #2
    lda (z80_ix),y         ; y coordinate in hl.
    clc
    adc z80_c        ; add cosine lb
    sta (z80_ix),y        ; store new coordinate lb.
    iny
    lda (z80_ix),y
    adc z80_b        ; add cosine lb
    sta (z80_ix),y        ; store new coordinate hb.

 

...

AGD porting notes (what is required to port AGD to a new system)

When asked if there is a guide to porting AGD to a new system, this was Kees van Oss's response on facebook:

Not really ... but this is how MPAGD works and what needs to be done to port it:

1. You start with an ASCII AGD file with commands to define graphics and the game behaviour. This AGD file can be created by converting an existing AGD4.7 game or create one with AGDX Studio or Jonathan Cauldwells WinAGD program.

2. The next step is to compile this ASCII AGD file into an assembler source file. The compiler converts all ASCII AGD commands into assembler code and adds the engine to the assembler sourcefile.
The engine is a library with routines which are called by the assembler code linked to the AGD commands.

3. After compiling, you need to assemble the assembler file into a binary file ready to run on the designed system. This assembler creates a tape or diskfile which can be used by the emulator.

4. After creating the tape or disk files, an emulator is called with the created tape or diskfile to test the game. So what needs to be changed to port MPAGD are:

- The converter, a C program (Step 1)
- The compiler, a C program (Step 2)
- The engine, a Z80 assembler file (Step 2)

You can use an existing assembler and emulator program to complete steps 3 and 4.

Things that need to be defined for a platform are:

- memory map definition
- screen handling
- sound handling
- keyboard handling

All blocks, sprites and objects are software handled by peeking and poking into screen memory so there is no hardware sprite handling except the MSX port which handles hardware sprites. The screen is based upon the ZX Spectrum, 256x192 pixels. The Spectrum has 16 colours with the limitation of a 8x8 block with 2 colours

- Blocks (tiles) are 8x8 pixels, max 255
- Sprites are 16x16 pixels, max 12
- Objects are 16x16 pixels, max 255

All these specs can be changed but all AGD4.7 games are based upon these specs.

Are you planning to port MPAGD to another platform because we have a Developers environment where you can discuss your porting problems.

Thursday, February 27, 2020

several thousand lines later...

A lot of progress has been made, but... is it a bad thing for a game engine not to call functions like "shoot"?  I have a feeling I'll be looking at the original Z80 code.  On the bright side, I'm nearing the half way point converting the code.

The engine would be faster if the data structures stored X, and Y coordinates next to each other.  But I can't fix that since the game design tool would need rewritten.

Wednesday, February 26, 2020

... and another

This is a particularly egregious subroutine for the 6502.
I'm tired, so I'll have to double check the code later, but the 6502's 48 instructions are reduced to just 19 on the 6803. 

The 16 bit X index register, 16 bit D register, and not having to write the contents of HL until we need to change X makes a huge difference.  The 6502 has to store pointers on the direct page, and they are updated a byte at a time.  The 65816 supports 16 bits, so it should be more like the 6803 here.  The mode switching between 8 & 16 bit registers that can kill it's performance shouldn't be much of an issue.



;----------------------------------------------------
; Explosion shrapnel.
;----------------------------------------------------

shrap:
;    ldy #1
;    lda (z80_ix),y         ; get the angle.
;    clc
;    adc #<shrsin        ; shrapnel sine table.
;    sta z80_l
;    lda #>shrsin
;    adc #0
;    sta z80_h

    ldx        z80_ix

    ldab    1,x            ; get the angle
    ldx        #shrsin        ; shrapnel sign table
    abx                    ; X now contains z80_hl

;    ldy #0
;    lda (z80_hl),y         ; fetch value from table.
;    sta z80_e
;    inc z80_l         ; next byte of table.
;    bne :+
;    inc z80_h
;:
;    ldy #0
;    lda (z80_hl),y        ; fetch value from table.
;    sta z80_d
;    inc z80_l        ; next byte of table.
;    bne :+
;    inc z80_h
;:
;    ldy #0
;    lda (z80_hl),y         ; fetch value from table.
;    sta z80_c
;    inc z80_l         ; next byte of table.
;    bne :+
;    inc z80_h
;:
;
;    ldy #0
;    lda (z80_hl),y         ; fetch value from table.
;    sta z80_b

    ldd        2,x            ; fetch value from table
    std        z80_bc
    ;order changed because we use de below
    ldd        ,x            ; fetch value from table
    std        z80_de
    stx        z80_hl        ; still need to add 4 to hl, wait until done with de

;    ldy #2
;    lda (z80_ix),y         ; x coordinate in hl.
;    clc
;    adc z80_e        ; add sine lb
;    sta (z80_ix),y        ; store new coordinate lb.
;    ldy #3
;    lda (z80_ix),y
;    adc z80_d        ; add sine hb
;    sta (z80_ix),y        ; store new coordinate hb.

    ldx        z80_ix
    ; D still contains z80_de
    add        2,x            ; x coordinate,
    std        2,x            ; store new coordinate

;    ldy #4
;    lda (z80_ix),y         ; y coordinate in hl.
;    clc
;    adc z80_c        ; add cosine lb
;    sta (z80_ix),y        ; store new coordinate lb.
;    ldy #5
;    lda (z80_ix),y
;    adc z80_b        ; add cosine lb
;    sta (z80_ix),y        ; store new coordinate hb.

    ldd        4,x            ; y coordinate          
    add        z80_bc        ;    add cosine
    std        4,x            ; store new coordinate
  
    ldd        z80_hl        ; add 4 to hl
    addd    #4
    std        z80_hl

    rts

6502 vs 6803 code size example

Okay, who enabled auto completion by default on Notepad++?  This should be associate with the language rather than a global setting.  Now I have to turn it off, and on when I switch between C, and assembly.  😈

Since nobody's getting circuit boards out of China before CoCoFest, I don't feel a lot of pressure to write some code for a couple hardware projects I promised to help with.  So, I'm translating more code from 6502 to 6803 for the Teaser project.

Just to give you an idea of the difference in code size, I've commented out the 6502 instructions, and placed the equivalent 6803 ones after each section.  Notice how 8 instructions become 2 after iniob0, and 4 of the 6502 instructions are some of the slowest on that CPU?  It's like this everywhere.

The Z80 references are due to the original code the 6502 is ported from coming from the Z80, and they are duplicating the register use with memory variables.  Since the 6803's index register X is 16 bit, and can index anywhere in a 256 byte range off of X, we don't need to even change X here.  The 16 bit D register even lets us load, and save two bytes at once even though they are separate variables.
The 6803 is far superior for accessing data structures, and this project uses a lot of them.

The on significant difference vs the 6502, is the 8 bit loop counter is placed in memory, and decremented there.  Too bad Motorola didn't offer a direct addressing version of DEC, and INC instructions.  The dearth of registers on the 6803 makes the direct page an obvious place for loop counters.

Sorry, if Blogger does bad things to the code formatting.  I need to look up the page I was using to format, and colorize the code with off of my old computer.

;-------------------------------------------------------------
; Initialise all objects.
;
; Reset current room,y,x to start room,y,x for all objects
;-------------------------------------------------------------

iniob:
;    lda #<objdta         ; objects table.
;    sta z80_x
;    lda #>objdta
;    sta z80_i
;
;    ldx numob         ; number of objects in the game.

    ldx        #objdta        ; object table
    stx        z80_ix
    ;*************** use memory to hold loop counter
    ldaa    numob    ; number of objects in the game
    staa    loopcounter
   
iniob0:
;    ldy #35
;    lda (z80_ix),y         ; start screen.
;    ldy #32
;    sta (z80_ix),y         ; set start screen.
;    ldy #36
;    lda (z80_ix),y         ; find start y.
;    ldy #33
;    sta (z80_ix),y         ; set start y.

    ldd        35,x        ; start screen, find start y
    std        32,x        ; set start screen, start y

;    ldy #37
;    lda (z80_ix),y         ; get initial x.
;    ldy #34
;    sta (z80_ix),y         ; set x coord.

    ldaa    37,x        ; get initial x.
    staa    34,x        ; set x coord.

;    clc             ; point to next object.
;    lda z80_x
;    adc #38            ; distance between objects.
;    sta z80_x
;    bcc :+
;    inc z80_i
;:
    ldaa    #38        ; distance between objects.
    abx                ; point to next objects.

;    dex             ; repeat.
;    bne iniob0
   
    dec        loopcounter
    bne        iniob0
   
    rts

Tuesday, February 25, 2020

more on github

I just pushed the 6502 version of the code to print text on a graphics screen.
When I get time, the Atom, Atari, and Plus/4 code needs separated, and then I need to interface the code to the C compiler.

Monday, February 24, 2020

Teaser

This is something I started shortly before I got crazy busy last year.

What could I be translating from 6502 to 6803 assembly, and why does it keep saying z80?
😎

<sigh> Only 6000+ lines left to translate.

;--------------------------------------------------------------
; Display sprites.
;
; Input:
;  IX = sprite table
;--------------------------------------------------------------

dspr:
;    lda #(NUMSPR/2)        ; number of sprites to display.
;    sta sprcnt
    ldx        z80_ix
    ldaa     #(NUMSPR/2)        ; number of sprites to display.
    staa     sprcnt
dspr0:
;    ldy #0
;    lda (z80_ix),y         ; get sprite type.
;    cmp #255         ; is it enabled?
;    bne dspr1         ; yes, it needs deleting.
    ldx        z80_ix
    ldaa    0,x            ; get sprite type
    cmpa    #255        ; is it enabled?
    bne        dspr1        ; yes, it needs deleting.
dspr5:
;    ldy #5
;    lda (z80_ix),y         ; new type.
;    cmp #255        ; is it enabled?
;    bne dspr3         ; yes, it needs drawing.
    ldx        z80_ix
    ldaa    5,x            ; new type.
    cmpa    #255        ; is it enabled?
    bne        dspr3         ; yes, it needs drawing.
dspr2:
;    ldy #5
;    lda (z80_ix),y         ; copy new type.
;    ldy #0
;    sta (z80_ix),y
;    ldy #6
;    lda (z80_ix),y         ; copy new image number.
;    ldy #1
;    sta (z80_ix),y
    ldx        z80_ix
    ldd        5,x                ;copy new type 5 and image number 6
    std        0,x                ;> to 0 & 1
;    ldy #7
;    lda (z80_ix),y         ; copy new frame.
;    ldy #2
;    sta (z80_ix),y
    ldaa    7,x            ; copy new frame
    staa    2,x
;    ldy #8
;    lda (z80_ix),y         ; copy new y.
;    ldy #3
;    sta (z80_ix),y
;    ldy #9
;    lda (z80_ix),y         ; copy new x.
;    ldy #4
;    sta (z80_ix),y
    ldd        8,x            ; copy new y & x
    std        3,x
   
;    clc
;    lda z80_x
;    adc #(TABSIZ*2)        ; distance to next odd/even entry.
;    sta z80_x
;    lda z80_i
;    adc #0
;    sta z80_i         ; next sprite.
    ldd        z80_ix
    addd    #(TABSIZ*2)        ; distance to next odd/even entry. next sprite.
    std        z80_ix
   
    dec sprcnt
    bne dspr0            ; repeat for remaining sprites.
    rts
dspr1:
;    ldy #5
;    lda (z80_ix),y         ; type of new sprite.
;    cmp #255        ; is this enabled?
;    bne dspr4         ; yes, display both.
    ldx        z80_ix
    ldaa    5,x            ; type of new sprite
    cmpa    #255        ; is this enabled?
    bne        dspr4        ; yes, display both.
dspr6:
    jsr sspria             ; show single sprite.
    jmp dspr2

; Displaying two sprites.  Don't bother redrawing if nothing has changed.

dspr4:
;    ldy #4
;    lda (z80_ix),y        ; old x.
;    ldy #9
;    cmp (z80_ix),y         ; compare with new value.
;    bne dspr7         ; they differ, need to redraw.
;    ldy #3
;    lda (z80_ix),y        ; old y.
;    ldy #8
;    cmp (z80_ix),y         ; compare against new value.
;    bne dspr7        ; they differ, need to redraw.
    ldx        z80_ix
    ldd        3,x            ; a = old y, b = old x
    cmpa    9,x
    bne        dspr7        ; they differ, need to redraw.
    cmpb    8,x            ; compare against new value.
    bne        dspr7        ; then differ, need to redraw.

;    ldy #2
;    lda (z80_ix),y         ; old frame.
;    ldy #7
;    cmp (z80_ix),y         ; compare against new value.
;    jmp dspr7         ; they differ, need to redraw.
    ldaa    2,x            ; old frame.
    cmpa    7,x            ; compare against new value.
;    jmp    dspr7            ; they differ, need to redraw
    bne        dspr7        ; they differ, need to redraw
   
;    ldy #1
;    lda (z80_ix),y         ; old image.
;    ldy #6
;    cmp (z80_ix),y         ; compare against new value.
;    beq dspr2        ; everything is the same, don't redraw.
    ldaa    1,x            ; old image.
    cmpa    6,x            ; compare against new value.
    beq        dspr2        ; everything is the same, don't redraw.
dspr7:
    jsr sspric         ; delete old sprite, draw new one simultaneously.
;    jmp dspr2
    bra    dspr2
dspr3:
    jsr ssprib         ; show single sprite.
;    jmp dspr2
    bra    dspr2
   
sprcnt:    .byte 0

The magic MC-10 keyboard trick

On the last episode of the CoCoTalk podcast (talk show?) the news section brought up the following video, where a BASIC program reads garbage from the keyboard when you wave your hand over it.


https://youtu.be/o6zssRDSjuE

I gave a brief explanation of why this happens on the show, but here is a little more detail about what is going on.


The Motorola 6803 is a microcontroller. It differs a bit from most 8 bit microprocessors because it has some built in hardware.  Parallel I/O ports, serial port, timer, etc...  To keep things somewhat simple, the MC-10 keyboard is wired to one of the built in parallel I/O ports.  The program shown above sets that port to input mode, and then it just polls the input port, and prints whatever comes in on the screen.

The way the keyboard is wired to the 6803, it forms it's own buss of sorts on the system.  The wires and circuit board traces form little antennas which pick up noise.  It's been a while, but if I remember right, the human body can induce a current of up to 1.8 volts.  I don't have a scope to hook up to it for verification, but that's probably what we'd see.  While the port on the 6803 was designed to work with 5 volt parts, it seems just sensitive enough to pick up that voltage as high signals.  Since the voltage isn't continuous on all the lines, the numbers change somewhat randomly.

If the keyboard had used a 2 layer board with a ground plane on the top side, and just passed the key connections through from/to the other side, this probably wouldn't happen.  Also, if the keyboard buss had resistors tying the keyboard lines to ground on the read side of the circuit, that weak noise would have been dropped to a level that the 6803 wouldn't read.  I don't think this was a matter of money, the engineer probably just didn't see it as a buss, so he didn't expect it, and this didn't show up in testing.

So why doesn't it cause a problem for BASIC?  The BASIC interpreter outputs data to the keyboard to choose which row of keys to check, it performs debounce which dumps inconsistent data, etc...
I don't think the debounce is helping.  More likely, the 6803's I/O port design can't read that low of a voltage under those circumstances, and that only happens when it's set just as input and you poll it, but that's a bit of a guess.

Thursday, February 20, 2020

Tuesday, February 18, 2020

The code for the expansion board I was working on for the VZ200 is up on github.
VZ Super-Expander


The IDE interface was going to be based on the TRS-80 Lo Tech interface.
The CPLD was just going to be used for address decoding to keep the pin count down.  That would require some external chips for buffering, LED, etc..., but it was only two or three parts I remember right.  The driver was going to be based on modified code from the Lo Tech driver just to keep things simple.


My project to do list:


A chess game for the MC-10.  People asked me to do this, so some point in the next few months I'll see what I can do about it.  They suggested I port MicroChess from the 6502, but if I can get the 6803 C compiler to actually build working code, you'll get a lot better chess game than that.  The compiler seems to have some stack issues at the moment, so no promises. 

More MC-10 ROM changes in the works, including a faster LOG function.  The new LOG will eliminate some of the slow division in the current code, replacing it with multiplication that will use the hardware multiply instead.  Functions that depend on LOG should be significantly faster, including SQR, SIN, and COS.  Combined with the previous SIN, COS speedup, the 0.89 MHz MC-10 might beat the 1.77 MHz CoCo 3 generating that "Fedora" 3D plot, and Ahl's Benchmark will drop below the 1 minute mark, possibly around 45 seconds.  That's half the factory ROM's original time.  Another change is to drop the ELSE statement.  Yeah, that's the first thing I added, but after the last round of changes, it's just slowing things down.  The interpreter has to search for the end of the line looking for an ELSE statement when an IF fails.  Without it, the interpreter just loads the address of the next line, and starts interpreting code.  Hopefully, that will speed up non-math oriented code enough to top the 10% mark.

Port BASIC to a 68HC11 development board.  I've made a lot of the changes already, but it will only use terminal I/O, so lots of stuff has to go.  At the moment, the board is just sitting on my desk staring at me. 

A few years ago I ported the UCSD Pascal P-Code (bytecode) interpreter to the 6803.  The 16 bit support, 16 bit index register, and a few other features makes the code smaller, and faster than the 6502 version (the Apple Language System).  I *think* all that's left to implement is the hardware interface code for the UCSD P-Machine.  But it's never that easy is it?  The MC-10 hardware is right in the middle of the memory map, and there is no disk drive.  The MC-10's design does allow external hardware to disable the internal memory map (video, sound, ROM, and internal RAM), so, it just needs an external expansion that can disable this stuff.  The MCX-128 will do some of this, but it doesn't work with the hi-res mode, so using my 64 column graphics text code is out.  That leaves the 32 column, uppercase only, inverse "lowercase", VDG output for text.  That would be horrid for Pascal.  Maybe some hardware is needed here.  Hmmmm...

The P-Code interpreter for Tiny Pascal (BYTE Magazine, 1978) may get a port.  It's similar to UCSD Pascal, but it's simpler.  A program could be compiled on the PC, and the bytecode could be tacked on to the end of the interpreter, allowing the whole thing to load from cassette.  It might be fun to play with, but it's not a priority.

While I'm talking about bytecode interpreters... the author of FastBASIC for the Atari asked if I'd port the it's bytecode interpreter to the 6803.  It would need over 2000 lines of assembly.  I have avoided starting on it until I finish some other projects, but a few people may prefer BASIC over Pascal.

Finish the disassembly of the VZ-200 ROM.  I was using msys (a Unix like development system that works under Windows), but someone broke the sed command in an update.  The disassembly uses an automated script to generate code, labels, and to attach comments to the disassembly using sed.  My new desktop machine has a Linux boot drive I can use when things like this happen, and hopefully sed isn't broken there as well.


I'm going to start uploading code to github including:
 
The Oric music player, the Apple II Mockingboard version, and the VZ200 version.

A port of the William Tell Overture 4 voice music program from the CoCo, to the VZ.  This is unfinished since I no longer have hardware to test on, and having someone else in Australia test it just wasn't working. It had some sort of bug as of the last test, which I may have found, but it doesn't have all the music data.  I don't have the magazine with the source code anymore, so I'd have to extract the data from the CoCo executable.

Some Veralog code for a VZ200 RAM, FLASH, IDE, sound board I was working on.  It's just some address decoding, generating chip selects, and a small amount of address line generation for the paged memory.  The pin count was a bit high for a small CPLD, so I was planning changes, but my VZ burned up with my house, so it hasn't been touched since.  It's about 600 lines of verilog.

The 64 column, graphics text code for the 6502, Z80, and 6803.
That includes Atom, Atari, Plus/4, VZ200, and MC-10 versions. 
The Plus/4 code still needs to set the graphics mode, and the memory map.
The Z80 VZ, and 6803 MC-10 versions have some untested optimizations.
As I work on this, I'll post video updates.  Hopefully the quality will be better now.

Monday, February 17, 2020

No I'm not dead... not yet anyway

No I'm not dead, and my projects aren't dead.  I just got busy working for several months, and I've had some computer issues. One laptop is totally dead and the other is kinda in two pieces.  My new PC (AMD Ryzen 2700X), is gradually getting all the tools installed including multiple compilers, assemblers, custom syntax highlighting definitions, disassemblers,  Quartus, PCB design tools...

Some projects are going to be placed on github, including some projects I've never mentioned.