Let's make a computer

Discussion in 'Public Member Events' started by jkrmnj, May 27, 2016.

  1. Thanks. Once we get to where we can start building I will message you about it.

    That is cool. I didn't realize transparent blocks couldn't be charged.

    I completely skipped over that part while reading it :p

    I am pretty sure this one is actually not mentioned. For jumping, there appears to be a JNZ, JC, and JP. Trying to do something like while(x < y) would be a massive pain and incredibly slow. It seems like the only way is to continuously do y-1 until it either reaches x or 0. Depending on the size of x, that could take a very long time. There appears to be room for one more jump condition though and adding something like JLT (jump if less than 0) would be great. Checking the comparison is just checking the most significant bit for 1 assuming we use two's compliment. From there, you could accomplish pretty much any of the conditions with ease. For example:
    while(x >= y)
    [LOOP]
    ....
    SUB A, B ;A=y B=x
    JLT LOOP ;if(x<y) then keep looping
    JNZ END ;if(x!=y) then stop looping
    JP LOOP ;
    [END]
    ....
    607 likes this.
  2. When you need to save on hardware, you have to adjust the software ... modify the algorithm to use the provided instruction set. Having loop count in a register and decrementing towards zero is common practice.
    Some CPUs have the instruction "DJNZ" = "decrement and jump if not zero" for this purpose.

    This is the same as JC

    while (x >= y) do_something;

    Note this is same as while ( ! (x < y)) ..., so if x - y sets carry then exit loop

    Code:
    ; A=x B=y - note that I swapped them compared to your example
    
    loop:
    
        CMP A, B  ; same as SUB A, B but without modifying A, only flags are set
    
                          ; carry flag is set if A < B
    
        JC end
    
        do_something
    
        JP loop
    
    end:
    
  3. Here is a square root algorithm I mostly adapted from Wikipedia. I think it works correctly but I may have made some silly mistakes. It also definitely doesn't work for decimals and only works with 8bit numbers. Coding in assembly feels weird compared to higher level languages :p. Sometimes I find myself trying to do it one way only to realize I am taking shortcuts that don't exist.

    Code:
    DEFINE INPUT 0xC0 
    DEFINE OUTPUT 0xE0
    start:
    LD D, INPUT
    LD A, (D)
    LD B, A
    LD D, 00000000
    LD C, 01000000 ;No idea if this is the right way to load a constant
    LD A, C
    [LOOP] ;while (a>b)
    CMP A, B
    JC GREATER ;exit the loop
    SHR ;Shift a register right twice
    SHR ;Not sure what parameter whould be since seems like it just shifts A right
    JP LOOP ;continue the loop
    [GREATER]
    LD C, A ;Move it back to C
    LD A, B
    JNZ LOOP2 ;This is the first check.
    JP LOOPEND 
    [LOOP2] ;while (b != 0)
    LD A, B
    JNZ CONTINUE ;Continue with loop
    JP ENDOFLOOP ;End the loop
    [CONTINUE]
    LD A, C
    ADD A, D
    LD E, A
    LD A, B
    CMP A, E ; E=res+bit
    JC ELSE ;if num >= res+bit (from the wikipedia page)
    SUB A, E
    LD B, A
    LD A, D
    SHR
    ADD A, C
    LD D, A
    JP ENDOFIF
    [ELSE]
    LD A, D 
    SHR 
    LD D, A
    [ENDOFIF]
    LD A, C
    SHR
    SHR
    LD C, A
    [LOOPEND]
    LD A, D
    LD E, OUTPUT
    LD (E), A
    
    If I counted correctly, it is around 52 bytes. This would use about 20% of the total space if we went for the 8bit PC