Copying Chars from b400 to hires screen

Here you can ask questions or provide insights about how to use efficiently 6502 assembly code on the Oric.
User avatar
barnsey123
Flight Lieutenant
Posts: 379
Joined: Fri Mar 18, 2011 10:04 am
Location: Birmingham

Copying Chars from b400 to hires screen

Post by barnsey123 »

Calling ASM dudes,

There is probably a very simple answer to this but I'm stumped. I'm trying to copy some standard charset chars from b400 to a hires screen. I can print SPACE ok (char 32) but any other char I get garbage.
correct using HCHAR, wrong using ASM
correct using HCHAR, wrong using ASM
viksplodge2.png (2.52 KiB) Viewed 15196 times
In the pic above, the circled bit are the results I get from using an ASM routine. It SHOULD look like the main picture (produced using curset + hchar). I've got the right location and the right color but - somehow, the wrong data.

First the C code which sets some variable values and calls the asm code - chasm()
The variable deadtoggle controls wether to print spaces or pieces.

Code: Select all

void deadpile(){
  unsigned char tmpchar;
  if (playertype == 2){	// ATTACKERS
	  if ( deadtoggle ) deadattackers++;
	  deadplayers=deadattackers;
	  deadcurset=0xa025;          // correct location for dead attackers column (works)
	  tmpchar=0xb400+(41*8);   // ")" = char 41 - this does not seem to work
  }
  if (playertype == 1){ // DEFENDERS
	  if ( deadtoggle ) deaddefenders++;
	  deadplayers=deaddefenders;
	  deadcurset=0xa027;        // correct location for dead defenders column (works)
	  tmpchar=0xb400+(40*8); // "(" = char 40 - this does not seem to work
  }
  
  if ( deadplayers ){
	  for (x=0;x<deadplayers;x++){
		  deadchar=tmpchar; // copy the value of tmpchar to deadchar (used in asm routine)
		  if ( deadtoggle == 0 ) deadchar=0xb400+(32*8); // space (works)
		  chasm(); // print char at given location
		  deadcurset+=360; // 40*9 (advance a line - Works)
	  }
  }
 
}
and now the asm code

Code: Select all

_chasm
.(
	lda _deadcurset+0
	sta tmp1+0
	lda _deadcurset+1
	sta tmp1+1
        ; print 7 rows of data 
	ldx #7 
loop
	ldy #0
        ; load the value stored at deadchar 
	lda _deadchar
        ; print it on the screen
	sta (tmp1),y 
        ; now advance to the next byte of the characters bit pattern
	jsr _IncDeadChar 
        ; advance to the next row
	jsr _Add40
	dex
	bne loop
	rts
.)

; add one to the value of deadchar to get the next byte of the bit pattern
_IncDeadChar
.(
	clc
	lda _deadchar+0
	adc #1
	sta _deadchar+0
	bcc skip
	inc _deadchar+1
skip
	rts
.)
I think I'm close but there's something I'm missing and I can't see it (can anybody show me where I'm going wrong?)

Puzzled and delayed
Barnsey
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: Copying Chars from b400 to hires screen

Post by Dbug »

barnsey123 wrote:Calling ASM dudes,
There is probably a very simple answer to this but I'm stumped. I'm trying to copy some standard charset chars from b400 to a hires screen. I can print SPACE ok (char 32) but any other char I get garbage.
When you call hires() the charsets are moved from B400 to 9800, else they would be in the middle of the HIRES video memory.
User avatar
barnsey123
Flight Lieutenant
Posts: 379
Joined: Fri Mar 18, 2011 10:04 am
Location: Birmingham

Re: Copying Chars from b400 to hires screen

Post by barnsey123 »

Someone shoot me! I spent a week on that problem...I just assumed the ASM code was wrong. Doh!

Thanks dbug...I can sleep now. :)
User avatar
ibisum
Wing Commander
Posts: 1643
Joined: Fri Apr 03, 2009 8:56 am
Location: Vienna, Austria
Contact:

Re: Copying Chars from b400 to hires screen

Post by ibisum »

The 80's were a long time ago. ;) I went "d'oh!" too ..
User avatar
barnsey123
Flight Lieutenant
Posts: 379
Joined: Fri Mar 18, 2011 10:04 am
Location: Birmingham

Re: Copying Chars from b400 to hires screen

Post by barnsey123 »

hmmm...wasn't as simple as just changing the start address of the hires charset area ($9800). I found it difficult to use a variable in place of a hard coded address (I can't work out a way to do it), I can't use "lda _deadchar,x" where deadchar was set to, say "0x9800 + (41*8)". The code below works but it's a bit clumsy (from "loop" onwards anyway). What's the best way to do this?

On the plus side the current code is smaller and faster and I'm learning more about ASM.

Code: Select all

_chasm
.(
	lda _deadcurset+0
	sta tmp1+0
	lda _deadcurset+1
	sta tmp1+1
	ldx #0
loop
	; check to see if a space is to be printed
	lda _deadtoggle
	cmp #0
	beq chasmspace	; set the space char
	lda _playertype	; if not a space then either defender or attacker
	cmp #1			; is it a defender?
	beq chasmdef	; playertype=defender
	lda $9948,x		; else playertype=attacker
chasmx
	ldy #0
	sta (tmp1),y       ; store line x of the char at correct location
	jsr _Add40          ; move to next line
	inx                    
	cpx #7
	bcc loop
	rts
chasmspace
	lda $9900,x
	jmp chasmx
chasmdef
	lda $9940,x
	jmp chasmx
.)
User avatar
Chema
Game master
Posts: 3013
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Copying Chars from b400 to hires screen

Post by Chema »

I am not sure if I got you, but it seems that you only want to change the base address to either $9900, $9940 or $9948 for all the loop depending on some condition.

Well, what I usually do is using self-modifying code for that. It sounds tricky but it is not. It would be something as:

Code: Select all


bases .byt 00, $40, $48
_chasm
.(
   lda _deadcurset+0
   sta tmp1+0
   lda _deadcurset+1
   sta tmp1+1

  ; Get the correct address. As the high byte is always $90, we only need
  ; the low value, which can be fetched from a table
  ldx _deadtoggle
  lda bases,x
  
 ; Now place it by patching the code
 sta smc_address+1

 ; Now proceed...
   ldx #6       ; Does the loop go from 0 to 6 (both inclusive)?
loop
   ; check to see if a space is to be printed
smc_address
   lda $9900,x      ; the low byte is modified above!!!
   ldy #0            ; I guess you need to set this back to zero because it is modified by _Add40
   sta (tmp1),y       ; store line x of the char at correct location
   jsr _Add40          ; move to next line
   dex                   
   bpl loop
   rts
.)
I also reversed the way the loop works. It is usually easier to start with the highest value and go decrementing until the negative flag is set. That happens automatically with the dex, so no need to make the comparison.

Or I might have completely misunderstood you... I am currently tired ;)
Did not test, of course, so there may be bugs lurking... But you get the idea.

EDIT: I just noticed that you are checking two variables to get the low byte of the address, not just one, so the trick with the table won't work... Anyway just a couple of lines of code more should patch that...
User avatar
barnsey123
Flight Lieutenant
Posts: 379
Joined: Fri Mar 18, 2011 10:04 am
Location: Birmingham

Re: Copying Chars from b400 to hires screen

Post by barnsey123 »

Thanks chema, I will have a play with this tomorrow.

By the way, I found out what the garbage was...it was a binary procession... Somehow it was displaying a counter...1,2,3,4,5...and not part of a char...
Post Reply