Sprite Blues in CP/M v2.2

Started by AMSDOS, 11:56, 10 September 10

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AMSDOS

I've been trying to incorporate Sean McManus' XOR Sprite routine from his ESD2 program into my own programs in CP/M, it seems to be a reasonible routine and I can use his Sprite Definer Program to define sprites, thus only to be having trouble making it work properly in CP/M!  :(  I managed with the help of Kevin Thacker to make workable Sprite Routine in CP/M which works extremely well and fast, it's only setback unfortunately is the border around the sprite which prevents the sprite from spreading itself across the screen. Here's the demo:

     org &100
     ld a,0
     call &be9b
     defw &bc0e
     ld bc,&0101
     call &be9b
     defw &bc38
     call setcolors
     call initialise
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
.mainloop
     call control
     jp mainloop
.conkey
     call &be9b
     defw &bb1e
     ret
.exit
     call &be9b
     defw &bb03
     ld a,2
     call &be9b
     defw &bc0e
     jp 0
.setcolors
     ld hl,sprcolor
     ld a,0
.colloop
     ld c,(hl)
     ld b,c
     push af
     push hl
     call &be9b
     defw &bc32
     pop hl
     pop af
     inc hl
     inc a
     cp 10
     jr c,colloop
  .control
     ld a,8
     call conkey
     jr nz,moveleft
     ld a,1
     call conkey
     jr nz,moveright
     ld a,0
     call conkey
     jr nz,moveup
     ld a,2
     call conkey
     jp nz,movedown
     ld a,66
     call conkey
     jr nz,exit
     ret
  .moveleft
     ld a,&0
     ld hl,(xpos)
     cp h
     jp nz,doleft
  .showleft
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld de,(scradr)
     ld hl,sprdata
     ld b,8
     ld c,15
     call disspr
     ret
  .doleft
     ld hl,(xpos)
     dec h
     ld (xpos),hl
     jp showleft
  .moveright
     ld a,&46
     ld hl,(xpos)
     cp h
     jp nz,doright
  .showright
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld de,(scradr)
     ld hl,sprdata
     ld b,8
     ld c,15
     call disspr
     ret
  .doright
     ld hl,(xpos)
     inc h
     ld (xpos),hl
     jp showright
  .moveup
     ld a,&0
     ld hl,(xpos)
     cp l
     jp nz,doup
  .showup
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
     ret
  .doup
     ld hl,(xpos)
     dec l
     ld (xpos),hl
     jp showup
  .movedown
     ld a,&b6
     ld hl,(xpos)
     cp l
     jp nz,dodown
  .showdown
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
     ret
  .dodown
     ld hl,(xpos)
     inc l
     ld (xpos),hl
     jp showdown
  .findcolumn
                            ;; H = x coordinate (0-79)
                            ;; L = y coordinate (0-199)
                            ;; HL = screen address (top-left of sprite)
     push bc                    ;; store BC because we are modifying it in this
                                ;; routine
     push de                    ;; store DE because we are modifying it in this
                                ;; routine
     ld c,h                     ;; store x coordinate in C register
     ld h,0                     ;; L = y coordinate, H = 0
     add hl,hl                  ;; double L. Now L is a byte offset from the
                                ;; start of the table pointing to the
                                ;; entry corresponding to screen Y
                                ;; coordinate. We double because each entry
                                ;; is two bytes.
     ld de,table                ;; base of table
     add hl,de                  ;; add offset to base to get actual address in
                                ;; memory of the table entry
     ld a,(hl)
     inc hl
     ld h,(hl)
     ld l,a                     ;; HL = value from table. it is the screen
                                ;; address for the start of this line
                                ;; corresponding to the Y coordinate
     ld b,0                     ;; BC = x coordinate as a 16-bit value. C = x
                                ;; coordinate
     add hl,bc                  ;; add on X coordinate
                                ;; HL = final screen coordinate for x,y position
     pop de                     ;; restore registers we used
     pop bc
     ret
.initialise
     ld de,table
     ld hl,&c000
     ld b,&19
.next
     push bc
     push hl
     ld b,&8
.loop
     push bc
     ld a,l
     ld (de),a
     inc de
     ld a,h
     ld (de),a
     inc de
     ld bc,&800
     add hl,bc
     pop bc
     djnz loop
     pop hl
     ld bc,&50
     add hl,bc
     pop bc
     djnz next
     ret
.disspr
     ld a,b
     ld (pl+1),a
.loop1
     push de
.pl
     ld b,&0
.loop2
     ldi
     inc c
     djnz loop2
     pop de
     ld a,d
     add &8
     ld d,a
     jr nc,end
     ld a,e
     add &50
     ld e,a
     ld a,d
     adc &c0
     ld d,a
  .end
     dec c
     jr nz,loop1
     ret
  .table
     defs 400
  .scradr
     defw &c000
  .xpos
     defb &00
  .ypos
     defb &00
  .scrrow
     defb 0
  .sprcolor
     defb 0,26,0,6,3,15,18,1,2,20,0
  .sprdata
     defb 12,12,12,12,12,12,12,12
     defb 8,0,0,0,0,0,0,4
     defb 8,0,&54,&fc,0,0,0,4
     defb 8,0,&a9,3,&a8,0,0,4
     defb 8,0,&f0,&f0,&a0,0,0,4
     defb 8,&44,&f0,&a0,&a0,0,0,4
     defb 8,&44,&e4,&70,&a0,0,0,4
     defb 8,&44,&b0,&10,&20,0,0,4
     defb 8,&44,&b0,0,0,0,0,4
     defb 8,0,&e4,&30,&20,&68,0,4
     defb 8,0,&83,&e9,&83,&16,&80,4
     defb 8,&41,&d6,&fc,&a8,&68,0,4
     defb 8,0,&56,&56,2,0,0,4
     defb 8,0,&c3,&41,&82,0,0,4
     defb 8,0,0,0,0,0,0,4
     defb 12,12,12,12,12,12,12,12


Unfortunately I cannot remember the problems I had with this program, though I recall the findcolumn routine was from Kev, the Display Sprite (disspr) routine was in AA53 - from what it appears is in it's original state.

But with Sean's routine from his BASIC set this is what I've ended up doing - just to see if I could apply it in straight Assembly in CP/M. This following routine is the one in BASIC which clearly works fine:

ORG &4000
write"spritexr.bin"

LD HL,YVAL
LD DE,XVAL
CALL &BC1D
PUSH HL
LD DE,SPRITE
EX DE,HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL
EX DE,HL
POP HL
.NOTZERO 
PUSH BC
PUSH HL
.LOOP 
LD A,(DE)
XOR (HL)
LD (HL),A
INC HL
INC DE
DJNZ LOOP
POP HL
LD BC,&0800
ADD HL,BC
JR NC,EXIT
LD BC,&C050
ADD HL,BC
.EXIT 
POP BC
DEC C
JR NZ,NOTZERO
RET
.XVAL
DEFW 100
.YVAL
DEFW 100
.SPRITE DEFB &08
DEFB &02
DEFB &00
DEFB &00
DEFB &30
DEFB &C0
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &30
DEFB &C0
DEFB &00
DEFB &00


I did a little debugging to see what &BC1D was returning in HL & BC, by dumping the values in empty memory locations and found that the result was different in BASIC when compared to CP/M. I'm guessing it's this which is having a bearing on what the final result looks like. Here's my CP/M program:

ORG &100
WRITE "spritexr.com"

LD A,1
CALL &BE9B
DEFW &BC0E ;; SCR_MODE_1

LD HL,YVAL
LD DE,XVAL
CALL &BE9B
DEFW &BC1D ;; SCR_DOT_POSITION
LD (&5000),HL ;; Memory address of the pixel

LD (&5010),BC ;; C Contains the Bit Mask for this pixel
                      ;; B contains the number of pixels stored in a byte minus one
PUSH HL
LD DE,SPRITE
EX DE,HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL
EX DE,HL
POP HL
.NOTZERO 
PUSH BC
PUSH HL
.LOOP 
LD A,(DE)
XOR (HL)
LD (HL),A
INC HL
INC DE
DJNZ LOOP
POP HL
LD BC,&0800
ADD HL,BC
JR NC,EXIT
LD BC,&C050
ADD HL,BC
.EXIT 
POP BC
DEC C
JR NZ,NOTZERO
RET
.XVAL
DEFW 100
.YVAL
DEFW 100
.SPRITE DEFB &08
DEFB &02
DEFB &00
DEFB &00
DEFB &30
DEFB &C0
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &30
DEFB &C0
DEFB &00
DEFB &00


Any ideas on what maybe happening I would be extremely greatful for, unfortunately this is only one of Sean's routines I'm looking at and maybe looking to adapt a couple of his other ones - Fine Force routine, Fine Overlay Routine & Fine Grab Routine, fortunately their only small routines, though are reasonibly effective!

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

arnoldemu

It's possible the upper rom is active in the area &c000-&ffff?
So you may need to use KL ROM DISABLE and KL ROM ENABLE around your sprite drawing code.
Are you getting graphical corruption which looks weird?

If you were using CPM+ then I would also suggest that the ram configuration needed altering with KL_BANK_SWITCH or similar.

Writing to screen ram will work, but reading will get rom contents.
XOR (HL) will do a read from HL and then combine it with the value in the A register.

(On a side note, I looked a the cpm2.2 version of dr.logo - curious after a post by Mr. Emmanuel Roche mentioned about it), and the first thing it did was jump into the rom, it seemed the amsdos rom was active at the point it was run. The amsdos rom does some work and then calls back into the program - yes half of the amsdos rom is dr.logo for cpm2.2!! And yes, it uses the firmware functions for drawing and text and not gsx)
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

AMSDOS

arnoldemu wrote:

It's possible the upper rom is active in the area &c000-&ffff?
So you may need to use KL ROM DISABLE and KL ROM ENABLE around your sprite drawing code.
Are you getting graphical corruption which looks weird?


Yes, the dimensions of the sprite are correct (8x8 in this case) though it's all scrambled, and it seems to change when my Xpos & Ypos values change (if that means anything).

If you were using CPM+ then I would also suggest that the ram configuration needed altering with KL_BANK_SWITCH or similar.

Fortunately I'm not using CP/M+  ;)

Writing to screen ram will work, but reading will get rom contents.
XOR (HL) will do a read from HL and then combine it with the value in the A register.

Okay, so if I do a KL U ROM DISABLE after a SCR DOT POSITION (&BC1D), will that be okay?  I just seem to be a little bit confused as to where the Sprite Routine resides cause the routine seems to be PUSHing, POPing & moving results around in the Registers before. I'm guessing all the real sprite work begins where I've defined the main LOOP routine, though the routine has to setup a number of Registers before it can display it onscreen.

(On a side note, I looked a the cpm2.2 version of dr.logo - curious after a post by Mr. Emmanuel Roche mentioned about it), and the first thing it did was jump into the rom, it seemed the amsdos rom was active at the point it was run. The amsdos rom does some work and then calls back into the program - yes half of the amsdos rom is dr.logo for cpm2.2!! And yes, it uses the firmware functions for drawing and text and not gsx)

I guess that would mean trouble would result if you had the ParaDOS ROM running instead. Sounds fascinating given it's relying on CPC Specifics to get the job done, though it does saves the problem of utilising Memory if GSX was required. GSX may have only been for CP/M+ though I do believe GSX was available for the 16bit versions of CP/M, CP/M-86 v1.1 for instance (which is the equivalent of CP/M v2.2) had it, though was only limited to CGA graphics. CP/M-86 did have 640Kb available for it though, so memory for that system was vast!

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

arnoldemu

Quote from: CP/M User on 12:47, 10 September 10
arnoldemu wrote:

It's possible the upper rom is active in the area &c000-&ffff?
So you may need to use KL ROM DISABLE and KL ROM ENABLE around your sprite drawing code.
Are you getting graphical corruption which looks weird?


Yes, the dimensions of the sprite are correct (8x8 in this case) though it's all scrambled, and it seems to change when my Xpos & Ypos values change (if that means anything).
Yes I think it's reading from rom.

Quote from: CP/M User on 12:47, 10 September 10
Writing to screen ram will work, but reading will get rom contents.
XOR (HL) will do a read from HL and then combine it with the value in the A register.

Okay, so if I do a KL U ROM DISABLE after a SCR DOT POSITION (&BC1D), will that be okay?  I just seem to be a little bit confused as to where the Sprite Routine resides cause the routine seems to be PUSHing, POPing & moving results around in the Registers before. I'm guessing all the real sprite work begins where I've defined the main LOOP routine, though the routine has to setup a number of Registers before it can display it onscreen.
looking at your code, do it around the loop routing that does the xor. before NOTZERO label and after the jr nz,NOTZERO.
So that it is only done one time for each sprite.

Quote from: CP/M User on 12:47, 10 September 10
(On a side note, I looked a the cpm2.2 version of dr.logo - curious after a post by Mr. Emmanuel Roche mentioned about it), and the first thing it did was jump into the rom, it seemed the amsdos rom was active at the point it was run. The amsdos rom does some work and then calls back into the program - yes half of the amsdos rom is dr.logo for cpm2.2!! And yes, it uses the firmware functions for drawing and text and not gsx)

I guess that would mean trouble would result if you had the ParaDOS ROM running instead. Sounds fascinating given it's relying on CPC Specifics to get the job done, though it does saves the problem of utilising Memory if GSX was required. GSX may have only been for CP/M+ though I do believe GSX was available for the 16bit versions of CP/M, CP/M-86 v1.1 for instance (which is the equivalent of CP/M v2.2) had it, though was only limited to CGA graphics. CP/M-86 did have 640Kb available for it though, so memory for that system was vast!
Yes exactly.

Well we can fit 576k to the cpc ;)
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

AMSDOS

arnoldemu wrote:

Yes I think it's reading from rom.
looking at your code, do it around the loop routing that does the xor. before NOTZERO label and after the jr nz,NOTZERO.
So that it is only done one time for each sprite.


Okay, I've applied it like this:

ORG &100
WRITE "spritexr.com"

LD A,1
CALL &BE9B
DEFW &BC0E ;; SCR_MODE_1

LD HL,YVAL
LD DE,XVAL
CALL &BE9B
DEFW &BC1D ;; SCR_DOT_POSITION
PUSH HL
LD DE,SPRITE
EX DE,HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL
EX DE,HL
POP HL
CALL &B903 ;; KL U ROM DISABLE
.NOTZERO 
PUSH BC
PUSH HL
.LOOP 
LD A,(DE)
XOR (HL)
LD (HL),A
INC HL
INC DE
DJNZ LOOP
POP HL
LD BC,&0800
ADD HL,BC
JR NC,EXIT
LD BC,&C050
ADD HL,BC
.EXIT 
POP BC
DEC C
JR NZ,NOTZERO
CALL &B900 ;; KL U ROM ENABLE
RET
.XVAL
DEFW 100
.YVAL
DEFW 100
.SPRITE DEFB &08
DEFB &02
DEFB &00
DEFB &00
DEFB &30
DEFB &C0
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &73
DEFB &EC
DEFB &30
DEFB &C0
DEFB &00
DEFB &00


This has got the correct image on display, unfortunately it's hanging CP/M if I run it a couple of times, even quicker if I do a CTRL-C, I'm guessing there's a Stack Overflow happening, not sure if CALLing KL U ROM DISABLE and KL U ROM ENABLE direct is correct procedure in CP/M or if I need to do an Enter Firmware (&BE9B) will try that again cause my KL U ROM DISABLE was in the Loop!  :-[  As thought the test was bad!  :(

Yes exactly.

Well we can fit 576k to the cpc
;)

Yes and still don't require GSX in CP/M 2.2!  ;D

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

arnoldemu

Do the call for those firmware functions with ENTER_FIRMWARE as normal.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

AMSDOS

arnoldemu wrote:

Do the call for those firmware functions with ENTER_FIRMWARE as normal.

Sadly CP/M doesn't like it at all, it just hangs there with the Disc Drive Whirring away without displaying anything!  :(  A disassembly of &B900 & &B903 shows that those routines are jumps to &BA5F and &BA66 so they aren't actually true Firmware instructions with RST 1,&<whatever>  instructions, so I'm guessing that's why it's not going at all.

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

arnoldemu

Quote from: CP/M User on 14:00, 10 September 10
arnoldemu wrote:

Do the call for those firmware functions with ENTER_FIRMWARE as normal.

Sadly CP/M doesn't like it at all, it just hangs there with the Disc Drive Whirring away without displaying anything!  :(  A disassembly of &B900 & &B903 shows that those routines are jumps to &BA5F and &BA66 so they aren't actually true Firmware instructions with RST 1,&<whatever>  instructions, so I'm guessing that's why it's not going at all.
Ok time to go direct to the hardware ;)

ld bc,&7f00+%10001100+mode
out (c),c

so for mode 1:
ld bc,&7f00+%10001100+1
out (c),c

and then to enable rom again:

ld bc,&7f00+%10000100+1
out (c),c

that may work?

hmmm.. unless there is a more friendly cpm 2.2 way of doing it?

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

AMSDOS

Sadly the hardware approach didn't work for me (simply colouring up the Text on screen), though I couldn't get it to go in BASIC either, not sure if it's the compiler, though the Compiler is happily generating the code.

Otherwise I need to look for CP/M programs which disable the upper ROMs, my program is almost running with the &B900 & &B903 routines though running it consistantly again and agin will eventually crash CP/M. Maybe the Stack Pointer is filling somewhere in that routine?


* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Have definitely established that KL U ROM DISABLE and KL U ROM ENABLE are somehow interfering with my routine. Unsure if it's CP/M it's interfering with or if the program is contributing to it's own demise, earlier I tried PUSHing and POPing the registers around both of those routines. What I just discovered is doing a KL U ROM DISABLE followed by a KL U ROM ENABLE alters the value in CP/M. Initally after doing a KL U ROM DISABLE the value stored is &86 in CP/M, though after KL U ROM ENABLE this value changes to &8E. I did a KL ROM RESTORE (&B90C) which on entry uses the value from the A register to restore the ROM to it's previous state. I thought it might of work, until <crash>.

This Bug is a weird one too, sometimes I can run the program upto nearly a Hundred times and on other occassions it's crashing after running the program 4 times! I thought perhaps the Protext and Maxam 1.5 ROMs might have been interfering with this program too, unfortunately no it was still crashing!  :(

John Eliott's got some stuff about the Amstrad Extended BIOS Calls which CP/M uses, though there doesn't seem to be anything there which might explain what's happening in my program. If anything his "USERF:" looks like CP/M Plus routine for accessing Firmware! Maybe CP/M Plus Specific given his love for the PCW!  ;D

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

The next part is scarey don't read it unless your game enough!

Spoiler: ShowHide
Well it seems my program works perfectly fine using CPCEMU15, though to be honest I cannot be 100% certain it's correctly running the program now. Cause all the trouble I'm having now is happening in Winape and I'm not even sure if that is the problem - or if Winape is simply doing close to what a real Amstrad would do. Unfortunately I don't have the means to get this going on my CPC!  :(  I would like to get Caprice32 running on my computer, unfortunately it won't go cause it's quite an involved DOS program & DOS on my current system is a shadow of what I had on my Pentium!  >:(  So it maybe an issue which needs to correctly resolve in Winape to allow this KL U ROM DISABLE & KL U ROM ENABLE to work properly, though it maybe working just fine and this error would happen on a Real CPC.

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

#11
Fortunately I was incorrect about the whole process of my assembly routine crashing CP/M being due to the Emulator. I tried a different approach with that routine and it seems to really show when it's been applied a lot. Unfortunately I will have to start again with something else. I have this other routine which works like the other one I first posted in the first thread. Unfortunately I haven't used it, but it requires the same information to the one I have in the first thread, so I gather it's simular. It works differently though depending on which Screen Mode your in. The Mode 1 bit looks like this:

Entry : DE = Screen Address to put sprite
        HL = Sprite Location
        B  = Sprite Width
        C  = Sprite Height
      LD A,B
      LD (p1+1),A
loop1:PUSH HL
p1:   LD B,&0
loop2:PUSH BC       
      LD A,(DE)     ; B Stores what's on the     
      LD B,A        ; screen
      LD C,(HL)     ; C Stores the byte of sprite
                    ; data
      LD A,C
      AND &88       ; Is pixel0 Used ?
      JR Z,jump1    ; If not, check pixel1
      LD A,B        ; Pixel0 is used, so reset
                    ; the
      AND &77       ; pixel0 that's currently on
      LD B,A        ; the screen
jump1:LD A,C
      AND &44       ; Is pixel1 used ?
      JR Z,jump2
      LD A,B
      AND &BB
      LD B,A
jump2:LD A,C
      AND &22
      JR Z,jump3
      LD A,B
      AND &DD
      LD B,A
jump3:LD A,C
      AND &11
      JR Z,jump4
      LD A,B
      AND &EE
      LD B,A
jump4:LD A,B        ; Merge sprite data byte with
                    ; screen
      OR C
      LD (DE),A     ; and display it on the
                    ; screen
      INC HL
      INC DE
      POP BC
      DJNZ loop2
      POP DE
      LD A,D        ;
      ADD &8        ;
      LD D,A        ;
      JR NC,end     ;
      LD A,E        ; Step down a line
      ADD &50       ;
      LD E,A        ;
      LD A,D        ;
      ADC &C0       ;
      LD D,A        ;
end:  DEC C
      JR NZ,loop1
      RET


It has these other routines for Mode 2 & Mode 0 and I'm presuming that they would look like these when applied to the routine above (MODE 2 first):

Entry : DE = Screen Address to put sprite
        HL = Sprite Location
        B  = Sprite Width
        C  = Sprite Height
      LD A,B
      LD (p1+1),A
loop1:PUSH HL
p1:   LD B,&0
loop2:PUSH BC       
      LD A,(HL)
      CPL
      LD C,A
      LD A,(DE)
      AND C
      OR (HL)
      LD (DE),A
      INC HL
      INC DE
      POP BC
      DJNZ loop2
      POP DE
      LD A,D        ;
      ADD &8        ;
      LD D,A        ;
      JR NC,end     ;
      LD A,E        ; Step down a line
      ADD &50       ;
      LD E,A        ;
      LD A,D        ;
      ADC &C0       ;
      LD D,A        ;
end:  DEC C
      JR NZ,loop1
      RET


MODE 0

Entry : DE = Screen Address to put sprite
        HL = Sprite Location
        B  = Sprite Width
        C  = Sprite Height
      LD A,B
      LD (p1+1),A
loop1:PUSH HL
p1:   LD B,&0
loop2:PUSH BC       
      LD B,(DE)
      LD C,(HL)
      LD A,C
      AND &AA
      JR Z,skip1
      LD A,B
      AND &55
      LD B,A
skip1:LD A,C
      AND &55
      JR Z,skip2
      LD A,B
      AND &AA
      LD B,A
skip2:LD A,B
      OR C
      LD (DE),A
      INC HL
      INC DE
      POP BC
      DJNZ loop2
      POP DE
      LD A,D        ;
      ADD &8        ;
      LD D,A        ;
      JR NC,end     ;
      LD A,E        ; Step down a line
      ADD &50       ;
      LD E,A        ;
      LD A,D        ;
      ADC &C0       ;
      LD D,A        ;
end:  DEC C
      JR NZ,loop1
      RET

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Oowe I hate it when I think I've got it right and it's not! This following Mode 0 routine has it's bugs - after PUSH BC they have LD B,(DE) which you cannot do, their first program has:

LD A,(DE)
LD B,A


which does the same job I'm hoping. I've altered this, but the my dam sprite isn't displaying for some reason. Here's the modified program below:

Entry : DE = Screen Address to put sprite
        HL = Sprite Location
        B  = Sprite Width
        C  = Sprite Height
      LD A,B
      LD (p1+1),A
loop1:PUSH HL
p1:   LD B,&0
loop2:PUSH BC       
      LD A,(DE)
      LD B,A
      LD C,(HL)
      LD A,C
      AND &AA
      JR Z,skip1
      LD A,B
      AND &55
      LD B,A
skip1:LD A,C
      AND &55
      JR Z,skip2
      LD A,B
      AND &AA
      LD B,A
skip2:LD A,B
      OR C
      LD (DE),A
      INC HL
      INC DE
      POP BC
      DJNZ loop2
      POP DE
      LD A,D        ;
      ADD &8        ;
      LD D,A        ;
      JR NC,end     ;
      LD A,E        ; Step down a line
      ADD &50       ;
      LD E,A        ;
      LD A,D        ;
      ADC &C0       ;
      LD D,A        ;
end:  DEC C
      JR NZ,loop1
      RET


And my program. I also tried this in AMSDOS, though got the same result.

     org &100
   
     write"cpmman3.com"
     ld a,0
     call &be9b
     defw &bc0e
     ld bc,&0101
     call &be9b
     defw &bc38
     call setcolors
     call initialise
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
.mainloop
     call control
     jp mainloop
.conkey
     call &be9b
     defw &bb1e
     ret
.exit
     call &be9b
     defw &bb03
     ld a,2
     call &be9b
     defw &bc0e
     jp 0
.setcolors
     ld hl,sprcolor
     ld a,0
.colloop
     ld c,(hl)
     ld b,c
     push af
     push hl
     call &be9b
     defw &bc32
     pop hl
     pop af
     inc hl
     inc a
     cp 10
     jr c,colloop
  .control
     ld a,8
     call conkey
     jr nz,moveleft
     ld a,1
     call conkey
     jr nz,moveright
     ld a,0
     call conkey
     jr nz,moveup
     ld a,2
     call conkey
     jp nz,movedown
     ld a,66
     call conkey
     jr nz,exit
     ret
  .moveleft
     ld a,&0
     ld hl,(xpos)
     cp h
     jp nz,doleft
  .showleft
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld de,(scradr)
     ld hl,sprdata
     ld b,8
     ld c,15
     call disspr
     ret
  .doleft
     ld hl,(xpos)
     dec h
     ld (xpos),hl
     jp showleft
  .moveright
     ld a,&46
     ld hl,(xpos)
     cp h
     jp nz,doright
  .showright
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld de,(scradr)
     ld hl,sprdata
     ld b,8
     ld c,15
     call disspr
     ret
  .doright
     ld hl,(xpos)
     inc h
     ld (xpos),hl
     jp showright
  .moveup
     ld a,&0
     ld hl,(xpos)
     cp l
     jp nz,doup
  .showup
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
     ret
  .doup
     ld hl,(xpos)
     dec l
     ld (xpos),hl
     jp showup
  .movedown
     ld a,&b6
     ld hl,(xpos)
     cp l
     jp nz,dodown
  .showdown
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
     ret
  .dodown
     ld hl,(xpos)
     inc l
     ld (xpos),hl
     jp showdown
  .findcolumn
                                ;; H = x coordinate (0-79)
                                ;; L = y coordinate (0-199)
                                ;; HL = screen address (top-left of sprite)
     push bc                    ;; store BC because we are modifying it in this
                                ;; routine
     push de                    ;; store DE because we are modifying it in this
                                ;; routine
     ld c,h                     ;; store x coordinate in C register
     ld h,0                     ;; L = y coordinate, H = 0
     add hl,hl                  ;; double L. Now L is a byte offset from the
                                ;; start of the table pointing to the
                                ;; entry corresponding to screen Y
                                ;; coordinate. We double because each entry
                                ;; is two bytes.
     ld de,table                ;; base of table
     add hl,de                  ;; add offset to base to get actual address in
                                ;; memory of the table entry
     ld a,(hl)
     inc hl
     ld h,(hl)
     ld l,a                     ;; HL = value from table. it is the screen
                                ;; address for the start of this line
                                ;; corresponding to the Y coordinate
     ld b,0                     ;; BC = x coordinate as a 16-bit value. C = x
                                ;; coordinate
     add hl,bc                  ;; add on X coordinate
                                ;; HL = final screen coordinate for x,y position
     pop de                     ;; restore registers we used
     pop bc
     ret
.initialise
     ld de,table
     ld hl,&c000
     ld b,&19
.next
     push bc
     push hl
     ld b,&8
.loop
     push bc
     ld a,l
     ld (de),a
     inc de
     ld a,h
     ld (de),a
     inc de
     ld bc,&800
     add hl,bc
     pop bc
     djnz loop
     pop hl
     ld bc,&50
     add hl,bc
     pop bc
     djnz next
     ret
.disspr
     LD A,B
     LD (p1+1),A
.loop1
     PUSH HL
.p1   
     LD B,&0
.loop2
     PUSH BC
     LD A,(DE)                  ; B stores what's on the
     LD B,A                     ; screen
     LD C,(HL)                  ; C stores the byte of sprite
                                ; data
     LD A,C
     AND &AA
     JR Z,skip1
     LD A,B
     AND &55
     LD B,A
.skip1
     LD A,C
     AND &55
     JR Z,skip2
     LD A,B
     AND &AA
     LD B,A
.skip2
     LD A,B
     OR C
     LD (DE),A
     INC HL
     INC DE
     POP BC
     DJNZ loop2
     POP DE
     LD A,D        ;
     ADD &8        ;
     LD D,A        ;
     JR NC,end     ;      LD A,E        ; Step down a line
     ADD &50       ;
     LD E,A        ;
     LD A,D        ;
     ADC &C0       ;
     LD D,A        ;
.end 
     DEC C
     JR NZ,loop1
     RET
  .table
     defs 400
  .scradr
     defw &c000
  .xpos
     defb &00
  .ypos
     defb &00
  .scrrow
     defb 0
  .sprcolor
     defb 0,26,0,6,3,15,18,1,2,20,0
  .sprdata
     defb 12,12,12,12,12,12,12,12
     defb 8,0,0,0,0,0,0,4
     defb 8,0,&54,&fc,0,0,0,4
     defb 8,0,&a9,3,&a8,0,0,4
     defb 8,0,&f0,&f0,&a0,0,0,4
     defb 8,&44,&f0,&a0,&a0,0,0,4
     defb 8,&44,&e4,&70,&a0,0,0,4
     defb 8,&44,&b0,&10,&20,0,0,4
     defb 8,&44,&b0,0,0,0,0,4
     defb 8,0,&e4,&30,&20,&68,0,4
     defb 8,0,&83,&e9,&83,&16,&80,4
     defb 8,&41,&d6,&fc,&a8,&68,0,4
     defb 8,0,&56,&56,2,0,0,4
     defb 8,0,&c3,&41,&82,0,0,4
     defb 8,0,0,0,0,0,0,4
     defb 12,12,12,12,12,12,12,12


* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Hmm, I managed to find the bugs in the Sprite Routine, which was "PUSHing HL" & "POPing DE"!  ::)  I even uncommented one of the statements which I did by accident in the Sprite Routine, but otherwise the PUSHing of HL onto the stack and POPing DE was in the magazine itself (AA53), meaning I had to go though and correct it!  :(  Now it seems to be writing something strange around my Sprite and in AMSDOS it's mangling it. Maybe because I've altered the sprite info!  :(

     org &4000
 
     ld a,0
     call &bc0e
     ld bc,&0101
     call &bc38
     call setcolors
     call initialise
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
.mainloop
     call control
     jp mainloop
.conkey
     call &bb1e
     ret
.exit
     call &bb03
     ld a,2
     call &bc0e
     jp 0
.setcolors
     ld hl,sprcolor
     ld a,0
.colloop
     ld c,(hl)
     ld b,c
     push af
     push hl
     call &bc32
     pop hl
     pop af
     inc hl
     inc a
     cp 15
     jr c,colloop
  .control
     ld a,8
     call conkey
     jr nz,moveleft
     ld a,1
     call conkey
     jr nz,moveright
     ld a,0
     call conkey
     jr nz,moveup
     ld a,2
     call conkey
     jp nz,movedown
     ld a,66
     call conkey
     jr nz,exit
     ret
  .moveleft
     ld a,&0
     ld hl,(xpos)
     cp h
     jp nz,doleft
  .showleft
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld de,(scradr)
     ld hl,sprdata
     ld b,8
     ld c,15
     call disspr
     ret
  .doleft
     ld hl,(xpos)
     dec h
     ld (xpos),hl
     jp showleft
  .moveright
     ld a,&46
     ld hl,(xpos)
     cp h
     jp nz,doright
  .showright
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld de,(scradr)
     ld hl,sprdata
     ld b,8
     ld c,15
     call disspr
     ret
  .doright
     ld hl,(xpos)
     inc h
     ld (xpos),hl
     jp showright
  .moveup
     ld a,&0
     ld hl,(xpos)
     cp l
     jp nz,doup
  .showup
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
     ret
  .doup
     ld hl,(xpos)
     dec l
     ld (xpos),hl
     jp showup
  .movedown
     ld a,&b6
     ld hl,(xpos)
     cp l
     jp nz,dodown
  .showdown
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ld hl,sprdata
     ld de,(scradr)
     ld b,8
     ld c,15
     call disspr
     ret
  .dodown
     ld hl,(xpos)
     inc l
     ld (xpos),hl
     jp showdown
  .findcolumn
                                ;; H = x coordinate (0-79)
                                ;; L = y coordinate (0-199)
                                ;; HL = screen address (top-left of sprite)
     push bc                    ;; store BC because we are modifying it in this
                                ;; routine
     push de                    ;; store DE because we are modifying it in this
                                ;; routine
     ld c,h                     ;; store x coordinate in C register
     ld h,0                     ;; L = y coordinate, H = 0
     add hl,hl                  ;; double L. Now L is a byte offset from the
                                ;; start of the table pointing to the
                                ;; entry corresponding to screen Y
                                ;; coordinate. We double because each entry
                                ;; is two bytes.
     ld de,table                ;; base of table
     add hl,de                  ;; add offset to base to get actual address in
                                ;; memory of the table entry
     ld a,(hl)
     inc hl
     ld h,(hl)
     ld l,a                     ;; HL = value from table. it is the screen
                                ;; address for the start of this line
                                ;; corresponding to the Y coordinate
     ld b,0                     ;; BC = x coordinate as a 16-bit value. C = x
                                ;; coordinate
     add hl,bc                  ;; add on X coordinate
                                ;; HL = final screen coordinate for x,y position
     pop de                     ;; restore registers we used
     pop bc
     ret
.initialise
     ld de,table
     ld hl,&c000
     ld b,&19
.next
     push bc
     push hl
     ld b,&8
.loop
     push bc
     ld a,l
     ld (de),a
     inc de
     ld a,h
     ld (de),a
     inc de
     ld bc,&800
     add hl,bc
     pop bc
     djnz loop
     pop hl
     ld bc,&50
     add hl,bc
     pop bc
     djnz next
     ret
.disspr
     LD A,B
     LD (p1+1),A
.loop1
     PUSH DE
.p1   
     LD B,&0
.loop2
     PUSH BC
     LD A,(DE)                  ; B stores what's on the
     LD B,A                     ; screen
     LD C,(HL)                  ; C stores the byte of sprite
                                ; data
     LD A,C
     AND &AA
     JR Z,skip1
     LD A,B
     AND &55
     LD B,A
.skip1
     LD A,C
     AND &55
     JR Z,skip2
     LD A,B
     AND &AA
     LD B,A
.skip2
     LD A,B
     OR C
     LD (DE),A
     INC HL
     INC DE
     POP BC
     DJNZ loop2
     POP DE
     LD A,D        ;
     ADD &8        ;
     LD D,A        ;
     JR NC,end     ;     
     LD A,E        ; Step down a line
     ADD &50       ;
     LD E,A        ;
     LD A,D        ;
     ADC &C0       ;
     LD D,A        ;
.end 
     DEC C
     JR NZ,loop1
     RET
  .table
     defs 400
  .scradr
     defw &c000
  .xpos
     defb &00
  .ypos
     defb &00
  .scrrow
     defb 0
  .sprcolor
     defb 0,26,0,6,3,15,18,1,2,20,0,0,0,0,0,0
  .sprdata
     defb 0,0,0,0,0,0,0,0
     defb 0,12,12,12,12,12,12,0
     defb 12,12,&54,&fc,12,0,0,0
     defb 12,12,&a9,3,&a8,12,0,0
     defb 12,12,&f0,&f0,&a0,12,0,0
     defb 12,&44,&f0,&a0,&a0,0,0,0
     defb 12,&44,&e4,&70,&a0,0,0,0
     defb 12,&44,&b0,&10,&20,0,0,0
     defb 12,&44,&b0,12,12,12,0,0
     defb 0,12,&e4,&30,&20,&68,0,0
     defb 0,12,&83,&e9,&83,&16,&80,12
     defb 12,&41,&d6,&fc,&a8,&68,12,0
     defb 0,12,&56,&56,2,12,0,0
     defb 0,12,&c3,&41,&82,12,0,0
     defb 0,12,12,12,12,12,0,0
     defb 0,0,0,0,0,0,0,0


* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

arnoldemu wrote:

(On a side note, I looked a the cpm2.2 version of dr.logo - curious after a post by Mr. Emmanuel Roche mentioned about it), and the first thing it did was jump into the rom, it seemed the amsdos rom was active at the point it was run. The amsdos rom does some work and then calls back into the program - yes half of the amsdos rom is dr.logo for cpm2.2!! And yes, it uses the firmware functions for drawing and text and not gsx)

Not sure if this is relevant to what you mentioned, however Borland developed some Graphics Applications to go with Turbo Pascal. Unfortunately neither of those programs are on NVG and I don't think I've noticed anything like them on the CP/M pages. There's Turbo Pascal Extension Graphics and Turbo Graphix. Turbo Graphix appears to only run on a 6128 while Turbo Pascal Extension Graphics appears to run across the board from a 464 to a PCW8512. Unsure if this means that it's the same program which would run across these systems, I'm guessing the PCW has it's own way of dealing with Graphics. It seems likely though that these programs were made by Borland exclusely for the Amstrads, of course I cannot be certain - the key term missing from those french ads (in the link) is GSX.

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

arnoldemu

Where did you get with the cpm version of this sprite drawing?

I'm ready to analyse it in a bit more detail.

It seems that:

1. Using ENTER FIRMWARE to call the firmware is good, provided you don't change the state of the upper ROM or change which ROM is active, because it relies on calling back into the AMSDOS ROM to go back to cpm after the firmware function.

2. ENTER FIRMWARE exists because I think CPM has taken over the RST the firmware normally uses.

3. The KL L ROM ENABLE/KL L ROM DISABLE is there, because that is where the firmware's interrupt exists. CPM 2.2 uses the firmware's interrupt.

4. So, to make it work for your code, you need to disable/enable the rom in a way which is compatible with the firmware and also with it's interrupt, either that or you have to turn off interrupts when you do your code.

5. It seems then that the alternative register set should not be touched by CPM 2.2 programs because the firmware interrupt would fail.

So what does this mean?

You'll have to hit the alternative register set direct. BC is used by firmware to store Gate-array rom and mode.

Do this before to disable rom:

exx
set 3,c ;; bit 3 - upper rom disable, turn off amsdos
out (c),c
exx


Now, access screen, but don't call any cpm functions or any other functions requiring enter firmware ;)
The firmware interrupt can remain active I think.

Then when you are done:

exx
res 3,c ;; bit 3 = upper rom enable (put amsdos back)
out (c),c
exx


So this effectively means most of the firmware jumpblock is useless in cpm, and so is some of the firmware rom functions ;)
Calling these direct will cause crashes.

So do these around your sprite drawing routine only and only where you need access to the screen, at other times, don't use them and call firmware functions.

Now, I've not looked at the firmware functions which read the screen, so I don't know if they disable the upper rom or not...

EDIT: For CPM+, I've no idea. Not looked at it yet.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

AMSDOS

OMG that sounds so technical, it's a very good in-depth explaination and I certainally hope it works - will give this a go.
My solution from this problem which is okay for the program I was making, was to move the screen from &C000 to &4000. Once the sprite routine was returning to where it should for the address range, all was working well there. The only limitation I have with this is the size the Compiled Pascal can be. Obviously if it's a program of considerable size and it needs to utilise that area &4000 onwards, then yeah that would be a problem. BOUNCY2.PAS is the result of it anyway, have a look if you think I maybe violating some protocal, the programs seems to be running fine as it is.
The only thing I think I would change is moving the Sprite Routine and the Sprite Data, I set those up as Constant Arrays, which in a COM file is going to have a place in that file (the routines are totally relocateable so it doesn't matter where they go in memory). I've found the Lara Monitor program to be an excellent tool to have when working with CP/M files and can easily sort out where everything is.

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

I wish I had good news, unfortunately it's still bad!  :(  Haven't tried it out on the Sprite Routine, but I'm getting the same problem using the Fast Plot Routine that's on CPCWiki and just thought that if it's doing that with the Fast Plot Routine, then it may happen with the Sprite Routines as well. For a moment I thought I might of had it working as it seems to be something I can run a number of times, before the program crashes the lot and keeps the Disc Drive Whirring away. Here's the program I made anyway:

ORG &0100

;; Test of FAST Plotting Routine for CP/M v2.2
;; Works in Mode 1.

write'fasplot.com'

.myprog
call &be9b
defw &bc02
LD a,1
call &be9b
defw &bc0e
LD a,2
call &be9b
defw &bc2c
ld (MYVAL),a
ld de,100
ld hl,100
CALL DISABLE_ROM
call fplot
CALL ENABLE_ROM
ld a,3
call &be9b
defw &bc2c
ld (MYVAL),a
ld de,101
ld hl,100
call DISABLE_ROM
call fplot
call ENABLE_ROM
ld a,1
call &be9b
defw &bc2c
ld (MYVAL),a
ld de,102
ld hl,100
CALL DISABLE_ROM
CALL fplot
CALL ENABLE_ROM
CALL &BE9B
DEFW &BB18
LD A,2
CALL &BE9B
DEFW &BC0E
RET

.DISABLE_ROM
EXX
SET 3,C  ;; Bit 3 - Upper ROM disable, turn off AMSDOS
OUT (C),C
EXX
RET

.ENABLE_ROM
EXX
RES 3,C  ;; Bit 3 - Upper ROM enable (put AMSDOS back)
OUT (C),C
EXX
RET
       
.FPLOT LD A, L   ;A = Lowbyte Y
AND %00000111  ;isolate Bit 0..2
LD H, A   ;= y MOD 8 to H
XOR L   ;A = Bit 3..7 of Y
LD L, A   ;= (Y\*8 to L
LD C, A   ;store in C
LD B, &60  ;B = &C0\2 = Highbyte Screenstart\2
 
ADD HL, HL  ;HL * 2
ADD HL, HL  ;HL * 4
ADD HL, BC  ;+ BC = Startaddress
ADD HL, HL  ;of the raster line
 
LD A, E   ;Lowbyte X to A
SRL D   ;calculate X\4, because
RR E   ;4 pixel per byte
SRL E
ADD HL, DE  ;+ HL = Screenaddress
 
LD C, %10001000  ;Bitmask for MODE 1
AND %00000011  ;A = X MOD 4
JR Z, NSHIFT  ;-> = 0, no shift
.SHIFT 
SRL C   ;move bitmask to pixel
DEC A   ;loop counter
JR NZ,SHIFT  ;-position
 
.NSHIFT
LD A,(MYVAL)  ;get color mask
XOR (HL)  ;XOR screenbyte
AND C   ;AND bitmask
XOR (HL)  ;XOR screenbyte
LD (HL), A  ;new screenbyte
RET   ;done

.MYVAL
DEFB 0


I've exercised caution with the Firmware by not using it in, tried a few things with the code, like Disabling Interrupts & Enabling them around the "FPLOT" routine, unfortunately it seems to always give in after I've executed the program after numerous goes.

Not the best example I had of this, though this is a rather primative program which plots 3 colours on screen Red, Yellow & Blue in succession, when they don't appear and the Disc Drive is Whirring away, then you know there's something happening which ain't right!  :(  I don't know perhaps the Fast Plotting routine is doing something which breaks one of those rules with regard to the Alternative Register Set - I Disabled the interrupts and Enabled them again around the routine, so I guess we can exclude that as being the cause for that crash. Only other thing I noticed earlier when I was using the KL U ROM DISABLE & KL ROM RESTORE (&B90C) was after doing a KL U ROM DISABLE the value returned into the Accumulator was &86, could that be having some bearing into what's happening here? Unfortunately I was using KL ROM RESTORE with that value and it didn't seem to make much difference - eventually crashing!  :(

It seems likely that it's possible to do and have applied some workarounds or used routines which are compatable - otherwise they would have revealed their horrible secrets long ago. I mentioned on the Amstrad Usenet Group about some arcade games for CP/M which RobotPD had in their catalogue, unfortunately they never seemed to have made the light of day on the Internet. This is the Disc in question though, "26300 Arcade games including Tetris clone Quatris, Pacman, Tornado, and Maze Chase. Some not CP/M 2.2: Tornado CP/M 2.2 only. Even CPC-Power hasn't mentioned those programs - they had quite a few Pacman PD programs, though all for AMSDOS.

I forgot I had it, but I actually made an Assembly program to draw a series of points, works along the same principals as the Drawing Loop I made which takes a series of points and draws the image onscreen, naturally it only uses GRA_PLOT_ABSOLUTE, though with a few adjustments it could be made to work with the Fast Plotting routine.

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Okay, I might have just solved this problem with that EOF marker, what might have been happening might have been because of my Assembly COM files. The rule in CP/M 2.2 (and I'm not sure if the same applies in CP/M Plus), is files must be divisable to 128 bytes. CP/M doesn't use headers, so .COM files always begin at &0100, and files in CP/M work as the number of Records - use STAT *.COM and you will see the number of RECs CP/M has for each file - by calculating that number by 128 bytes will give the size. as a consequence when the assembler was saving the COM file garbadge was being saved at the end of the file, regardless of wherever the EOF is, the file is going to save the next 128 bytes past that marker. I completely rearranged my file as a result, have put in the EOF marker at the end of the program and a bunch of 0s past that. Haven't had any trouble since, fingers crossed this was the problem!

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod