Gigatron Assembly Language

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
Post Reply
monsonite
Posts: 101
Joined: 17 May 2018, 07:17

Gigatron Assembly Language

Post by monsonite »

It's unlikely that most Gigatron owners get involved with the native 8-bit assembly language - because it is very much wrapped up in the ROM.

However, I have been working on a hardware simulation, using H. Neemann's "Digital" simulator, and I am now working at the native assembly level.

I have created a table of instructions and opcodes for the TASM assembler, and by using some macros, I can make the programming model of the Gigatron look a little more like a Z80, which is my most familiar cpu, from an assembly language point of view.

The Gigatron lacks an ADC (Add with Carry) instruction, and this is something I am currently trying to implement as a macro.

Would anyone with intimate knowledge of the native instruction set possibly explain how I can detect a carry and branch accordingly. Effectively making a macro for Branch on Carry Set.

Thanks in advance
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: Gigatron Assembly Language

Post by at67 »

Here's a truth table and K-Map I created for this exact problem:

Code: Select all

    // Calculate carry using signed 8bit representation for : r = a + b
    //
    // Sr = sgn(r), Sa = sgn(a), Sb = sgn(b), C = carry
    //
    //  Sr | Sa | Sb || C
    // ----+----+----++---
    //   0 |  0 |  0 || 0
    //   0 |  0 |  1 || 1
    //   0 |  1 |  0 || 1
    //   0 |  1 |  1 || 1
    //   1 |  0 |  0 || 0
    //   1 |  0 |  1 || 0
    //   1 |  1 |  0 || 0
    //   1 |  1 |  1 || 1
    //
    //     __ __ __             __
    //     Sa.Sb Sa.Sb Sa.Sb Sa.Sb 
    // __ +-----+-----+-----+-----+
    // Sr |  0  |  1  |  1  |  1  |
    //    +-----+-----+-----+-----+
    // Sr |  0  |  0  |  1  |  0  |
    //    +-----+-----+-----+-----+
    //
    //             __      __
    // C = Sa.Sb + Sr.Sb + Sr.Sa
    //             __
    // C = Sa.Sb + Sr.(Sb + Sa)
If you just want native code, then you'll need to do something like this:

Code: Select all

ld(AC,X)                        #10 Address of low byte to be added
adda(1)                         #11
st([vTmp])                      #12 Address of high byte to be added
ld([vAC])                       #13 Add the low bytes
adda([X])                       #14
st([vAC])                       #15 Store low result
bmi('.addw#18')                 #16 Now figure out if there was a carry
suba([X])                       #17 Gets back the initial value of vAC
bra('.addw#20')                 #18
ora([X])                        #19 Carry in bit 7
label('.addw#18')
anda([X])                       #18 Carry in bit 7
nop()                           #19
label('.addw#20')
anda(0x80,X)                    #20 Move carry to bit 0
ld([X])                         #21
adda([vAC+1])                   #22 Add the high bytes with carry
ld([vTmp],X)                    #23
adda([X])                       #24
st([vAC+1])                     #25 Store high result
bra('NEXT')                     #26
ld(-28/2)                       #27
This assumes the code is in page3 and there is no extra level of indirection.

The way it works is to add the low bytes of a two 16bit, (word), variables together and then check the sign bit of the 8bit result, if the sign is negative then AND the sign bits of the two input low bytes together, otherwise OR the sign bits of the two input low bytes together; this is your carry bit.

If you look at the final equation, you can see that's exactly what this code does.

For your particular use-case you would probably do something like this:

Code: Select all

ld(AC,X)                        #10 Address of low byte to be added
adda(1)                         #11
st([vTmp])                      #12 Address of high byte to be added
ld([vAC])                       #13 Add the low bytes
adda([X])                       #14
st([vAC])                       #15 Store low result
bmi('.addw#18')                 #16 Now figure out if there was a carry
suba([X])                       #17 Gets back the initial value of vAC
bra('.addw#20')                 #18
ora([X])                        #19 Carry in bit 7
label('.addw#18')
anda([X])                       #18 Carry in bit 7
nop()                           #19
label('.addw#20')
anda(0x80,X)                    #20 Move carry to bit 0
ld([X])                         #21
bne('wherever')                 #22 Branch on carry
monsonite
Posts: 101
Joined: 17 May 2018, 07:17

Re: Gigatron Assembly Language

Post by monsonite »

Thankyou for your excellent explanation.

I could not understand exactly what the AND / OR instructions were doing.

I was trying to work out how the carry was detected from Cout, not realising that it could be determined from the sign bit of the two operands.

This makes it clear now.

Thanks
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: Gigatron Assembly Language

Post by at67 »

monsonite wrote: 07 Apr 2022, 10:39 Thankyou for your excellent explanation.
My pleasure!
Post Reply