We're on Discord! Please join our server now if you don't want to miss anything! (More info) | Join the UCC4 contest! (More info)

* WalrusIRC & Discord main room

If you have a forum account, have more than 4 posts and are not part of a restricted usergroup, then you can chat in our main Discord server room directly from here and continue using the forums at the same time. Or you can join our server directly and access many more discussion rooms!

Author Topic: _iPhoenix_ tries to do Assembly things.  (Read 735 times)

0 Members and 1 Guest are viewing this topic.

Offline _iPhoenix_

  • Custom title
  • Super User
  • Join Date: Mar 2017
  • Location: Location
  • Posts: 668
  • Post Rating Ratio: +16/-1
  • ███████ ▼ ♪ Best music ♫
    • @dj_iPhoenix
    • @UCytgMNPxAMDsxjimvxHf01w
    • Legend-of-iPhoenix
    • @the-legend-of-iphoenix
    • My website.
  • Gender: Male
_iPhoenix_ tries to do Assembly things.
« on: July 09, 2018, 12:16:43 am »

Alright, so I've taken up learning Assembly, now that I am more comfortable with middle-to-lower level languages like C and C++, and I've progressed to the stage that I can start to write crappy programs now.


Here's my first actual assembly program. It's pretty bad. You can move a pixel around with the arrow keys. Mateo and PT_ helped me a bit with this one (Mateo helped me realize that the stack exists, and PT_ helped inspire the drawing code).


Code: [Select]
.nolist
#include "ti84pce.inc"
.list


  .org UserMem-2
  .db tExtTok, tAsm84CeCmp
 
  call _boot_ClearVRAM
  call _RunIndicOff
  ld de, $0050; de holds x coord
  ld c, $50; y coord stored in c
mainLoop:
  ld a, 1 ; draw
  call draw
  call keyWait
  push af ; dammit I love this trick.
    ld a, 0 ; erase
    call draw
  pop af
  call move
  ld a, b; if b is zero, we stop.
  or a, a
  jr z, quit ; relative jump is shorter, byte-wise
  jr mainLoop
quit:
  call _RunIndicOn
  ret
 
draw: ; draws our singular pixel (I set high goals)
      ; (whew this is a bit of work, it gave me lots of appreciation for the sprite routines others have made :P)
      ; we are using 16bpp mode here, so my routines
      ; (which are gently modified 8bpp routines) can
      ; probably be optimized
      ; takes input in a: 1 = draw the pixel, 0 = erase
  push bc ; save c onto the stack (as part of bc)
    ld b, 160d
    mlt bc ; this messes with c
    push bc ; thanks, Mateo
    pop hl
    add hl, hl ; hl * 2
    add hl, hl ; hl * 4 (2 bytes/pixel)
    add hl, de
    add hl, de ; hl += de * 2
    ld bc, vRam ; this also messes with c
    add hl, bc
    ld (hl), $ff ; byte 1
    inc hl
    or a, a
    jr z, _erase
_draw: ; label not needed, included for legibility.
    ld (hl), $00 ; byte 2
    jr _end
_erase:
    ld (hl), $ff ; byte 2
_end:
  pop bc ; restore bc (particularly c)
  ret
 
keyWait: ; waits for a key, keycode returned in a
  call _GetCSC ; get key codes
  or a, a; check scan codes by comparing a with itself (I got this "hack" from various routines, it is super clever)
  ret nz ; if a is not zero, return
  jr keyWait ; otherwise jump (relative jump saves bytes, according to my highly scientific testing)


move: ; input in a (getCSC code)
      ; moves the pixel by updating
      ; de (x coord) and c (y coord)
      ; nothing overly arcane happens
      ; I used to check if a was >= 5 or equal to skDel
      ; but my code caused bugs so I killed it (and the bugs)
   ld b, 1 ; we will set b to 0 if we want to quit
chk_Quit: ; label not used, but it increases legibility and does not harm anything (imho)
  cp skDel
  jp nz, chk_Down
  ld b, 0 ; we want to quit
  ret
chk_Down:
  cp skDown
  jp nz, chk_Left
  inc c
  ret
chk_Left:
  cp skLeft
  jp nz, chk_Right
  dec de
  ret
chk_Right:
  cp skRight
  jp nz, chk_Up
  inc de
  ret
chk_Up:
  cp skUp
  ret nz
  dec c
  ret


As you can probably tell, it's as optimized as I can get it, which is to say not very optimized. I realize these things come with time. [size=0]When will the Dunning-Kruger effect kick in? I like feeling competent...[/size] I'm trying to keep my code optimized and readable so I can look back on it later.


My current assembly setup is SC3 and the Project Builder. This is a temporary setup, and I'm switching to better tools soon. :)


Tips are always welcome.


  • Calculators owned: Two TI-84+ CE's
Please spam here: https://legend-of-iphoenix.github.io/spam/

"walruses are better than tuxedo chickens, all hail the great :walrii:" ~ me
Evolution of my avatar:

Offline mazhat

  • Full User
  • Join Date: Mar 2017
  • Location:
  • Posts: 189
  • Post Rating Ratio: +8/-0
  • Edelweiss. Edelweiss.
    • /u/Mazhat
    • Mazhat
    • @Mazhat
    • MOS
  • Gender: Male
Re: _iPhoenix_ tries to do Assembly things.
« Reply #1 on: July 10, 2018, 04:11:04 am »
I am glad you are pursuing Assembly!
I finished only one program, but I just don't know about
all the hacks, and tricks of the hardware to be even close to decent.
It's a real challenge for smarty pants, such as yourself.

I looked through my old files and found it,
also I know that the beginning isn't optimised,
but I didn't really feel like doing it lol.

Code: [Select]
;Low Quality Bootleg Sprite Routine
;Created By Matt C./ Mazhat
;
.NOLIST
#define   EQU   .equ
#define   equ   .equ
#define   END   .end
#define   end   .end
#include "ti83plus.inc"
#include "mirage.inc"
.LIST
     .org $9d93 ;Origin (set back two to account for AsmPrgm)
.db $BB,$6D ;Compiled AsmPrgm token
ret ;So TIOS wont run the program
.db 1 ;Identifier as MirageOS program
.db %00000000,%00000000 ;15x15 button
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db %00000000,%00000000
.db "Made by Matt C",0 ;Zero terminated description

;Program code starts here

;Reset the variables and such
ld a, 0
ld (posY), a ;Set posY
ld a, 0
ld (posX), a ;Set posX
ld a, $00
ld (animCounter), a

animation:
;
;Yes, I know this part is REALLY bad,
;BUT BOY AM I DONE WITH THIS PROGRAM.
call drawSprite
ld a, 0
ld (posX), a
call drawSprite
ld a, 1
ld (posX), a
call drawSprite
ld a, 2
ld (posX), a
call drawSprite
ld a, 3
ld (posX), a
call drawSprite
ld a, 4
ld (posX), a
call drawSprite
ld a, 5
ld (posX), a
call drawSprite
ld a, 6
ld (posX), a
call drawSprite
ld a, 7
ld (posX), a
call drawSprite

ld a, 0
ld (posY), a
call drawSprite
ld a, 1
ld (posY), a
call drawSprite
ld a, 2
ld (posY), a
call drawSprite
ld a, 3
ld (posY), a
call drawSprite
ld a, 4
ld (posY), a
call drawSprite
ld a, 5
ld (posY), a
call drawSprite
ld a, 6
ld (posY), a
call drawSprite
ld a, 7
ld (posY), a
call drawSprite


call drawSprite
ld a, 7
ld (posX), a
call drawSprite
ld a, 6
ld (posX), a
call drawSprite
ld a, 5
ld (posX), a
call drawSprite
ld a, 4
ld (posX), a
call drawSprite
ld a, 3
ld (posX), a
call drawSprite
ld a, 2
ld (posX), a
call drawSprite
ld a, 1
ld (posX), a
call drawSprite
ld a, 0
ld (posX), a
call drawSprite

ld a, 7
ld (posY), a
call drawSprite
ld a, 6
ld (posY), a
call drawSprite
ld a, 5
ld (posY), a
call drawSprite
ld a, 4
ld (posY), a
call drawSprite
ld a, 3
ld (posY), a
call drawSprite
ld a, 2
ld (posY), a
call drawSprite
ld a, 1
ld (posY), a
call drawSprite
ld a, 0
ld (posY), a
call drawSprite

ld a, (animCounter) ;Put counter into a
inc a ;increase a
ld (animCounter), a ;therefore increase counter
cp 5 ;animate five times
jp nz, animation

ld hl, textHello
b_call(_HomeUp) ;(CurCol) = 0, (CurRow) = 0.
b_call(_putS) ;Display String in HL

ret
animCounter:
.db $00
textHello:
.db "MADE IN ASM",0
DrawSprite:
ld ix, sprite ;Put sprite address into ix
;ld hl, plotsscreen ;First part of buffer
ld hl, 0 ;empty out the hl register
ld de, (posY) ;Get the Y position

;Check for Vertical Clipping (UP)
ld a, (posY)
ld c, $08 ;Else set the counter to 8
or a ;cp 0
jp m, clipUp ;If y-pos is negative

add hl, de ;mutliply Y by 12
add hl, de
add hl, de
add hl, hl
add hl, hl
ld bc, plotsscreen
add hl, bc
;Check for Vertical Clipping (down)
ld a, (posY) ;Get the Y Position
cp 56
jp p, clipDown ;If the sprite goes off screen
ld c, $08 ;Else set the counter to 8

;Finding the byte on the buffer where the sprite is
ld a, (posX) ;X-Position
ld de, 0 ;Empty de
bufByte:
cp 8 ;Check if less than 8
jp m, addOffsetX ;If Negative Return value (Return back)
sub 8 ;Take away 8 from 'a' register
inc de ;X Offset increase
jp bufByte ;Else repeat
addOffsetX:
add hl, de ;Add the x-offset to hl
shiftRight: ;We are bitshifting the sprite according to x, really
ld a, (posX) ;First lets see if it goes over the right side of the screen
or a ;Check if it goes over the screen
jp m, spriteLoop ;Skip if it does (If negative)

ld b, (ix) ;put sprite into b
ld a, (posX) ;put x-pos into a

ld de, 0 ;x-offset: set to zero
jp mod ;Get how many bitshifts we need (put into 'a' register)
;(For Previous Line: If it doesn't straddle on two bytes, skips to spriteLoop)
sr1:
;ld (LSD), a ;Get the amount we bitshifted by and put it into c for later use by shiftLeft
srl b ;Bitshift sprite right
dec a ;Decrease counter
or a ;cp 0
jp nz, sr1 ;If we're not done the shifting
ld (hl), b ;load sprite image into screen when finished shifting
shiftLeft: ;The byte we need to shift left (The second byte)
ld a, (posX) ;First lets see if it goes over the right side of the screen
cp 88 ;Check if it goes over the screen
jp p, spriteLoop ;Skip if it does


ld b, (ix) ;Put the sprite into b
inc hl ;X-Offset byte on buffer + 1
ld a, 8 ;Let's get the bytes we need to shift left using the number we used to shift right
sub e ;Get the left shift value (It will be negative)
;ld e, (LSD)
;sub e ;8-(# that we shifted right by) = How many left shifts we need for this byte
sl1:
sla b ;Bitshift sprite left
dec a ;Dec counter
or a ;cp 0
jp nz, sl1
ld (hl), b ;load sprite image into screen
dec hl
jp spriteLoop
drawToBuffer:
ld (hl), b ;load sprite image into screen
spriteLoop:
;ld (hl), b ;load sprite image into screen

dec c ;dec counter
ld a, c ;load counter into a

inc ix ;next sprite byte
ld de, 12
add hl, de ;next 'y' position on screen

cp $01 ;loop x8
jp p, shiftRight ;Drain the grain in the counter
b_call(_grBufCpy)
b_call(_grBufClr)
ret
clipDown:
sub 64 ;Take away 64 from Y-POS (register a)
NEG ;NEGATE IT
ld c, a ;Put that number into the counter for drawing sprites
jp shiftRight
clipUp:
ld de, plotsscreen ;Get the plotSScreen
add hl, de ;Put plotSScreen into hl
NEG ;Negate 'a' to get a positive value
CLUP:
dec a ;Counter: The amount of bytes that need to be skipped

dec c ;Remainer bytes to draw
inc ix ;Skip the byte

or a
jp nz, CLUP ;Keep skipping until we have the bytes we need to draw

jp shiftRight
mod:
ld e, a ;Get the amount we bitshifted by and put it into ** for later use by shiftLeft
cp 8 ;Check if The number is already a mutliple of eight (no need for bitshift)
jp z, drawToBuffer ;If zero just draw it without bit shifting anything
or a ;Due to technicality, 0 is not a multiple of 8
jp z, drawToBuffer ;So just do the same thing
cp 8
jp m, sr1 ;If Negative Return value (Return back)
sub 8 ;Take away 8 from 'a' register
jp mod ;Else repeat
;LSD:;leftShiftData:
.db $00
sprite:
.db %01111110
.db %10000001
.db %10100101
.db %10000001
.db %10100101
.db %10011001
.db %10000001
.db %01111110
posX:
.db 0
posY:
.db 0

end
« Last Edit: July 10, 2018, 04:17:41 am by mazhat »
  • Calculators owned: TI-83Plus, TI-84Plus
  • Consoles, mobile devices and vintage computers owned: Samsung TAB A (Cheap), DSI, Rasperry PI 3
The Mogami River.

Offline _iPhoenix_

  • Custom title
  • Super User
  • Join Date: Mar 2017
  • Location: Location
  • Posts: 668
  • Post Rating Ratio: +16/-1
  • ███████ ▼ ♪ Best music ♫
    • @dj_iPhoenix
    • @UCytgMNPxAMDsxjimvxHf01w
    • Legend-of-iPhoenix
    • @the-legend-of-iphoenix
    • My website.
  • Gender: Male
Re: _iPhoenix_ tries to do Assembly things.
« Reply #2 on: July 12, 2018, 10:32:20 pm »
A lot of fun progress has happened since that first post! I've decided on a very simple game where you (a square) walk around a screen collecting coins (also squares).







Features:
  • Slow!
  • Large!
  • Unoriginal!
  • Nut-free!
  • Low-quality graphics!
  • Documentation not included!
  • 80% All-natural!
  • Not a scam!


This game is clearly the pinnacle of ez80 programming and should be worshipped as such.
  • Calculators owned: Two TI-84+ CE's
Please spam here: https://legend-of-iphoenix.github.io/spam/

"walruses are better than tuxedo chickens, all hail the great :walrii:" ~ me
Evolution of my avatar:

Offline Caleb Hansberry

  • CodeWalrus Staff
  • Full User
  • Moderator
  • CodeWalrus Supporter
  • *
  • Safe-haven access
  • Join Date: Jan 2015
  • Location:
  • Posts: 220
  • Post Rating Ratio: +3/-0
  • I am a Christian
    • caleb_hansberry
    • JinnaiTamano
    • @https://soundcloud.com/caleb-hansberry
    • Skylites Computers
  • Gender: Male
Re: _iPhoenix_ tries to do Assembly things.
« Reply #3 on: July 15, 2018, 11:49:06 pm »
I'm also happy you're working on ez80 assembly. It's absolutely a worthwhile endeavor!
  • Calculators owned: TI-82, TI-83, TI-83+SE, TI-84+SE, TI-85, TI-89, TI-99/4A
  • Consoles, mobile devices and vintage computers owned: HP Portable Plus 110, Toshiba T3100, Toshiba T5200, GRiD 1660, TI-99/4A, Apple IIgs, and much more than I can list here

 


You can also use the following HTML or bulletin board code to share it on your page or forum signature!


Also do not forget to check our affiliates below.
Planet Casio TI-Planet Calc.news BroniesQC BosaikNet Velocity Games