ASM n00b needs some help...

Started by WacKEDmaN, 12:02, 23 November 22

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

WacKEDmaN

so today ive been playing around with some assembly in javacpc..
i took some examples from the wiki and chibiakumas site and sorta mixed a few bits
namely the Hardware scrolling byte by byte using the CRTC from the wiki...and chibis hello world..
i worked that out prity easily...

then i wanted to plot a simple diagonal line on a new keypress...
i setup the keypress..then had a look at the firmware calls for origin and plot..and set them up with the de and hl regs..

but im struggling to get it to plot more than once...

so started new just to plot the line... all i want to is a simple line from 0,0 to 100,100...
this is what i came up with.... (yeah yeah im a n00b!)
set_origin equ &bbcc  ; de=x hl=y
plot_absolute equ &bbea  ; de=x hl=y

org &2000

ld de,0
ld hl,0
call set_origin
ld a,0
jp plot_line
ret

plot_line:
inc de
inc hl
call plot_absolute
inc a
cp 100
ret
jr plot_line

it doesnt seem to 'ComPare' a=100 and just returns after the first plot without looping...

could someone give me a hint of my (probably totally obvious) screw up please?  :laugh:
i know theres probably faster ways to do it..but i just need the basics atm!

eto

use "ret z" instead of "ret". ret always returns but you want it to return only if a =100.
http://z80-heaven.wikidot.com/instructions-set:cp
http://z80-heaven.wikidot.com/instructions-set:ret


WacKEDmaN

#2
thanks eto!

but i tried that (you mean in the plot_line ret right?)
..that plots once then does nothing!.. and never returns to basic...

and thanks for the links! ...that site is better for instruction info than what i was looking at!

eto

probably the firmware routine destroys a. then you have to save it, e.g. on the stack.

pelrun

#4
You always need to check the details of the firmware calls to see which registers are corrupted and which are preserved; GRA PLOT ABSOLUTE kills AF, BC, DE and HL so you're pretty much left with IX/IY (slower to access) unless you use the stack.

And it's generally nicer to count backwards to zero when looping, and if you use B to hold the loop counter you can do the decrement/check/jump in one step with DJNZ.

(of course, don't forget the firmware has a line drawing function, so you don't have to plot every point individually :D )

  ld b,100
  call plot_line
  ret

plot_line:
  inc de
  inc hl
  push hl
  push de
  push bc
  call plot_absolute
  pop bc
  pop de
  pop hl
  djnz plot_line
  ret

McArti0

 &BBEA   GRA PLOT ABSOLUTE
      Action: Plots a point at an absolute user coordinate, using the
              GRA PLOT indirection

      Entry:  DE contains the user X-coordinate and HL holds the user
              Y-coordinate
      Exit:   AF, BC, DE  and  HL  are  corrupt,  and  all others are
              preserved

You must:

push af
push hl
push de
call plot_absolute
pop de
pop hl
pop af

...


cp 100
jr nz,plot_line
ret

or...

cp 100
ret z

jr plot_line
CPC 6128, Whole 6128 and Only 6128, with ........
TYPICAL :) TV Funai 22FL532/10 with VGA-RGB-in.

WacKEDmaN

#6
thank you both!!

i was just looking at push and pop.. but ..now i see i need to push and pop all the corrupt registers if i want to reuse them.... i forgot about that!

WacKEDmaN

#7
cool... went back to the original stuff i was playing with (line on keypress)... and its working great!

this is what ive got today...i think its not too bad for a first attempt in 30 odd years! (of course i didnt write it all.. most is borrowed like a good scriptkiddy would!)
org &4000

km_read_key equ &bb1b
mc_wait_flyback equ &bd19
scr_set_mode equ &bc0e
txt_output equ &bb5a
txt_invert equ &bb9c
set_origin equ &bbcc  ; de=x hl=y
plot_absolute equ &bbea  ; de=x hl=y

ld a,1
call scr_set_mode

ld hl,message
call display_message
call newline
call txt_invert
ld hl,message
call display_message

call gfx_origin


loop

call mc_wait_flyback
call update_scroll
call check_keys
halt
halt
jp loop

display_message:
ld a,(hl) ;Print a '255' terminated string
cp 255 ;if A reg = 255 do next line else skip..
ret z ;255 hit.. return to where ya come from!
inc hl
call txt_output
jr display_message

message: db 'Compiled with JavaCPC Z80 Assembler!',255

newline:
ld a,13 ;Carriage return
call txt_output
ld a,10 ;Line Feed
jp txt_output

gfx_origin:
ld de,0
ld hl,0
call set_origin
ret

plot_line:
inc de
inc hl
inc a
push de
push hl
push af
call plot_absolute
pop af
pop hl
pop de
cp 100
ret z
jr plot_line

check_keys:
call km_read_key
ret nc
cp 'P'     ; O
jp z,scroll_left
cp 'O'     ; P
jp z,scroll_right
cp 'p'     ; O
jp z,scroll_left
cp 'o'     ; P
jp z,scroll_right
cp 'l'
jp z,plot_line
ret


scroll_left:
ld a,(scroll_adjustment)
xor 1     ;; 0->1->0...
ld (scroll_adjustment),a
or a
ret z

;; get current scroll offset
ld hl,(scroll_offset)

;; update it
dec hl

;; ensure scroll offset is in range &000-&3ff
ld a,h
and &3
ld h,a

;; store new scroll offset. It is now ready to be written to the CRTC.
ld (scroll_offset),hl
ret


scroll_right:
ld a,(scroll_adjustment)
xor 1     ;; 0->1->0...
ld (scroll_adjustment),a
or a
ret z

;; get current scroll offset
ld hl,(scroll_offset)

;; update it
inc hl

;; ensure scroll offset is in range &000-&3ff
ld a,h
and &3
ld h,a

;; store new scroll offset. It is now ready to be written to the CRTC.
ld (scroll_offset),hl
ret

update_scroll:
;; write scroll adjustment
ld a,(scroll_adjustment)

add &f5   ;; This value alternates between &F5 and &F6
;; and controls the horizontal position of the visible
;; area on the monitor display. The effect these
;; values have on the position relies on the reaction
;; of the monitor to the horizontal sync output of
;; the CRTC. So for some monitors this may not result
;; in a smooth scroll as we want. This value may need
;; adjustment for your monitor and CRTC variant.
;;
;; From BASIC try the following two lines to see the
;; screen move, which is the basis of this effect:
;;
;; OUT &BC00,3:OUT &BD00,&F5 and
;; OUT &BC00,3:OUT &BD00,&F6

ld bc,&bc03   ;; select CRTC register 3 (horizontal sync width)
out (c),c
inc b
out (c),a   ;; set vertical and horizontal sync widths

ld hl,(scroll_offset)

;; write scroll offset (in CRTC character width units)
ld bc,&bc0c    ;; select CRTC register 12
out (c),c
ld b,&bd    ;; B = I/O address for CRTC register write

;; combine with scroll base
ld a,(scroll_base)
or h
out (c),a

ld bc,&bc0d    ;; select CRTC register 13
out (c),c
ld b,&bd    ;; B = I/O address for CRTC register write
out (c),l
ret


scroll_adjustment: defb 0

;; high byte of the screen base address
;; &00 -> screen uses &0000-&3fff
;; &10 -> screen uses &4000-&7fff
;; &20 -> screen uses &8000-&bfff
;; &30 -> screen uses &c000-&ffff

scroll_base: defb &30

;; the scroll offset in CRTC character units
scroll_offset: defw 0

WacKEDmaN

#8
one more question...
is it possible to ensure a register is set to zero when entering the function?

if they are already at 100 on entering the plot_line function (eg from pressing the key again).. they will continue to INC the line..
is it possible to loop inside the function without jumping back to its start...

like i want to set DE and HL when i enter it... but if i JR back they always gonna be reset to the first value..
eg.. something like...
plot_line:
            ld de,10
            ld hl,0
      .....jump back here...
            inc de
            inc hl
            inc a
     ......push, call plot_absolute, pops...
           cp 100
           ret z
           jr ...back up there^


is that possible? how would i go about that?!
..would i have to set it to jump back to that address where the INC starts?... how can i force the address?!

edit: i think i answed my own question with the jump back to the address....

   jr plot_line + 6 ; jump 6 bytes.. past the 2 LDs after plot_line

...i still dont get why it seems 200 long compared to a simple basic plot....
You cannot view this attachment.

WacKEDmaN

#9
SMH.. forgot the A register! :P

now its working perfect

plot_line:
 ld de,100
 ld hl,100
 ld a,0
 inc de
 inc hl
 inc a
 push de
 push hl
 push af
 call plot_absolute
 pop af
 pop hl
 pop de
 cp 100
 ret z
 jr plot_line + 8 ;jump 8 bytes after plot_line..past the 2 16bit and 1 8bit LDs

You cannot view this attachment.

andycadley

First of all, I'd avoid doing something like:

Jr plot_line + 6

As it's quite brittle if you need to change the code and the point of using an assembler is to avoid hand calculating all this stuff.

Instead put a suitable label where you want the jump to go to and use that instead. You aren't limited to having only one label at the start of a routine.You may want to come up with a good naming convention for these, or use local labels if your assembler supports them (can't remember if winape does)

Not sure what you mean about being 200 long. But I can't see you initialising A to zero at the start of plot_line, even though you seem to be using this to count how many times to loop. So I'd put money on that being the issue.

WacKEDmaN

#11
oh i can just use another label?  :doh:
thanks andy

plot_line:
ld de,100
ld hl,100
ld a,0
plot_return:
inc de
inc hl
inc a
push de
push hl
push af
call plot_absolute
pop af
pop hl
pop de
cp 100
ret z
jr plot_return

that is much easier to work with!

WacKEDmaN

#12
oh wow..moved that hw scroll and plot to my real cpc...
my GBS-8200 really doesnt like them CRTC routines!...yikes...

now i want a real monitor! LOL

eto

Quote from: WacKEDmaN on 16:06, 23 November 22oh wow..moved that hw scroll and plot to my real cpc...
my GBS-8200 really doesnt like them CRTC routines!...yikes...

now i want a real monitor! LOL

have you applied the GBSControl mod?

WacKEDmaN

#14
Quote from: eto on 16:50, 23 November 22
Quote from: WacKEDmaN on 16:06, 23 November 22oh wow..moved that hw scroll and plot to my real cpc...
my GBS-8200 really doesnt like them CRTC routines!...yikes...

now i want a real monitor! LOL

have you applied the GBSControl mod?
not entirely! only half way!.. i dont have the external clock setup... (i havent even looked for a module yet)
i tried playing with a few settings in gbs-c.. and got it a bit better..but the blue turned black..and it bounces around alot when it scrolls..flickers with the proper blue at the same time... it also seems to freeze and only sync occasionally if i hold the scroll on

WacKEDmaN

interestingly... the code works fine without gbs-c..just standard gbs8266 firmware handles it fine... ..i guess i really need the rest of the mod! :P   
..i know gbc-c works better for some games/demos.. but currently not so well with others..

Powered by SMFPacks Menu Editor Mod