Topic: ZX Spectrum machine code  (Read 8014 times)

Author Message

0 Members and 1 Guest are viewing this topic.

Offline moggy

  • Vic 20
  • **
  • Posts: 50
  • Kudos 9
    • View Profile
Re: ZX Spectrum machine code
« Reply #15 on: June 25, 2012, 07:23:47 PM »
I always thought DJNZ used B not C as its counting register (a quick flick through EA parrs' Z80 w/shop manual confirms this)

To use BC in a counting loop a JRNZ is required Not DJNZ using the accumulator to check the contents of B after decrementing and OR-ing with C then jumping when both are at 0.


Moggy

Offline Phu

  • RCM Workshop
  • Committee
  • Amiga 4000
  • *
  • Posts: 2084
  • Kudos 41
  • Gender: Female
  • Pay no attention to that PCB....
    • View Profile
    • ZX Spectrum Laptop Project
Re: ZX Spectrum machine code
« Reply #16 on: June 25, 2012, 09:59:37 PM »
Well, this is odd. Various Google results also show DJNZ as operating on B. But I could swear that I've written functional code using C and DJNZ before.

Well, anyways... LDIR is still a better way to do it ;)

moggy's BC decrement and zero test runs:

dec bc
ld a,b
or c
jr nz,<label>

If either b or c is anything other than zero, then the accumulator will be non-zero and the Z flag will clear, causing the NZ jump.

-- Richard
8 End of File, RCM:1

Offline carlsson

  • Vic 20
  • **
  • Posts: 60
  • Kudos 2
  • Gender: Male
    • View Profile
Re: ZX Spectrum machine code
« Reply #17 on: June 26, 2012, 09:43:40 AM »
Golly! Z80 (and X86) assembly code looks like a sea of instructions and registers to me, a 6502 guy. On the other hand I suppose it is a matter of exercise to wrap one's head around a different architecture.

Offline muguk

  • Sarcastic Git plc!
  • Administrator
  • Amiga 4000
  • ******
  • Posts: 3501
  • Kudos 32
  • Gender: Male
  • Mug U.K(tm)
    • View Profile
    • Mike's Word Toolbox
Re: ZX Spectrum machine code
« Reply #18 on: June 26, 2012, 11:09:13 AM »
I'll stick to 68000 - I understood that a lot more :)

Offline Panther

  • Committee
  • Amiga 4000
  • *
  • Posts: 4180
  • Kudos 35
  • Gender: Male
  • Look at the size of my.......Paws
    • View Profile
Re: ZX Spectrum machine code
« Reply #19 on: June 27, 2012, 07:52:46 AM »
Well I'm working my way through a book "Spectrum Machine Code for the Absolute Beginner"  :)

It's hopefully all sunk in about registers, although Flags is a bit different  :-\ It's then off to logical operators  ;D

Offline BassHead

  • Administrator
  • CPC 464
  • ******
  • Posts: 106
  • Kudos 7
  • Gender: Male
    • View Profile
Re: ZX Spectrum machine code
« Reply #20 on: June 27, 2012, 09:51:33 PM »
Well I'm working my way through a book "Spectrum Machine Code for the Absolute Beginner"  :)

Melbourne House? That's a good book if memory serves, it should see you okay, though I'm not expert  ;)
b(H)

Offline Panther

  • Committee
  • Amiga 4000
  • *
  • Posts: 4180
  • Kudos 35
  • Gender: Male
  • Look at the size of my.......Paws
    • View Profile
Re: ZX Spectrum machine code
« Reply #21 on: July 10, 2012, 02:01:05 PM »
Right I haven't given up on this yet, trying to draw a block of 8*8 pixel across the top of the screen

got this code

     org 33000
     ld hl,16383
     ld bc,32
loop
     inc hl
     push hl
     push bc
     ld de,256
     ld bc,8
loop2
     ld (hl),255
     add hl,de
     dec bc
     ld a,b
     or c
jp nz,loop2
     pop bc
     pop hl
     dec bc
     ld a,b
     or c
jp nz,loop
     ret

And when I run "Randomise USR 33000 it works  :), loop 2 draws the square, and the original loop moves to the next character block. I just wondered if there's a more efficient way of doing this, especially with Phu's previous example of LDIR which I think automatically increases HL whilst Decreasing BC.

Keeping track of the register values is bloody confusing !  :o
« Last Edit: July 10, 2012, 02:11:45 PM by Panther »

Offline Phu

  • RCM Workshop
  • Committee
  • Amiga 4000
  • *
  • Posts: 2084
  • Kudos 41
  • Gender: Female
  • Pay no attention to that PCB....
    • View Profile
    • ZX Spectrum Laptop Project
Re: ZX Spectrum machine code
« Reply #22 on: July 10, 2012, 02:29:28 PM »
Hi Stu,

It took me a while to figure out what you're doing, there but I got it eventually. The code is a reasonable enough method, though using BC for an 8-bit count is a bit wasteful. You can get the same by replacing ld bc with ld b, pop bc with pop b, push bc with push b, and the dec bc;ld a,b;or c;jp nz, with djnz.

Also, not sure why you start with 16383, since the first byte of the screen is 16384. By conincidence, the addressing means you do actually get the same effect, but you might not want to rely on that thinking ;)

I can't help feeling you're not taking advantage of the screen layout to do this easier. Your code is essentially doing 32 8-pixel blocks horizontally, and for each block fill one pixel line.

This is good if you're working with actual characters (and your ld (hl), source is something other than a constant), but if you're just filling the top 8 pixel lines of the screen (and you really don't want to cheat by filling in with attributes, which is easier and quicker) then I'm sure there's an easier way.

how about:

ld b,0
.loop
push b
ld hl,16384
ld (hl),255
add h,b
ld de,16385
add d,b
ld bc,31
ldir
pop b
inc b
ld a,b
cp 8
jp nz,loop
ret

This sets up a loop of 8 passes, each time adding the pass count (in b) to hl and de. Note that it adds to the upper byte, thus b=1 actually adds 256. Then it does the previous trick of copying n+1 = n using ldir and a count of 32 (note that ldir uses bc here, even though the value is less than 256).

Lastly, it copies b to a so we can use cp 8. The effect of cp is to perform a subtraction but not store the result. Thus when b = 8, 8 - 8 = 0, so the zero flag is set. Until b = 8, the loop continues.

Make sense?

-- Richard

8 End of File, RCM:1

Offline Panther

  • Committee
  • Amiga 4000
  • *
  • Posts: 4180
  • Kudos 35
  • Gender: Male
  • Look at the size of my.......Paws
    • View Profile
Re: ZX Spectrum machine code
« Reply #23 on: July 11, 2012, 02:48:43 PM »
Thanks Phu, see what you mean about using b instead of bc if the number value is 255 or less.

Well at least I managed to amaze my daughter by showing her how slow basic is at filling the screen line by line using plot & draw compared to filling it using machine code, even managed to change the creen attributes so it ran through all 256 combinations of paper, ink, bright and flash  :)

Still think I need some time to sit with Dr Phu and have him explain some sections of the book I've got, as it goes into storing character graphics in a sort of database format and then drawing them to screen from there.

Got a few more questions, so here goes;

Is it possible to output plain text to the display file ? or do you have to draw the text using each 8 -bit line  to make each character up ?

secondly,

if a created a loop like ;

loop2
     ld (hl),255
     add hl,de
     dec bc
     ld a,b
     or c
jp nz,loop2
ret

Can I then CALL that loop like a subroutine as in CALL, loop2 ?

Offline Phu

  • RCM Workshop
  • Committee
  • Amiga 4000
  • *
  • Posts: 2084
  • Kudos 41
  • Gender: Female
  • Pay no attention to that PCB....
    • View Profile
    • ZX Spectrum Laptop Project
Re: ZX Spectrum machine code
« Reply #24 on: July 11, 2012, 02:54:22 PM »
I believe (I may be wrong) that rst 16 with the ascii code in a can be used on a speccy to output text. The first 31 codes are control codes that allow things like ink and paper changes and positioning.

Alternatively, the character patterns are stored in ROM and are easy to get at. If you check the manual, there's an address that defines the start of the character patterns. It's stored so that you can do (ASCII char * 8) + address = start of 8 bytes of bit data for the character data. You can just copy from there.

Yes, you can use CALL in that way. When you do USR <n>, BASIC does CALL <n>. ret is the instruction to return from a subroutine entered with CALL.

-- Richard
8 End of File, RCM:1