Author Topic: The new fork of HuC  (Read 14055 times)

dshadoff

  • Full Member
  • ***
  • Posts: 175
Re: The new fork of HuC
« Reply #210 on: December 02, 2016, 12:44:55 PM »
Please, experts, give all your input (Like Dave, Tom, Elmer have) because I'm not one yet.

If you think of HuC as "PCE 101" in college, then I think ASM using the libraries to help you would be "PCE 201", and without libraries would be "PCE 220", if not a postgraduate course :-)

Although starting with setting up the system / banks / etc is a good idea, even for beginners to the PCE, I think some preexisting helper libraries are needed for the beginner after the basic HW init is done.

Well... how far down the rabbit hole do you want to go ?

Should we assume that the consumer of your work is familiar with assembler on another processor ?
...is aware that I/O is done via memory-mapped locations ?
...is aware that IDE's, performance profilers, and single-step debuggers all came after this machine was released ?
...is familiar with the concept that code can compile and not run properly, and it may not be obvious what is wrong because there is no operating system to intervene ?

I mean... 8-bit limitations and memory mapping to circumvent address space limitation will not be obvious to modern users, unless they write operating systems.

So, please define who you think your target audience is, or what you expect of them.

ccovell

  • Hero Member
  • *****
  • Posts: 2245
Re: The new fork of HuC
« Reply #211 on: December 02, 2016, 01:54:51 PM »
The target is: people who already know 6502, at least.  Probably some experience with NES or C64 programming.  Thus, it doesn't re-teach 6502 basics.

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: The new fork of HuC
« Reply #212 on: December 02, 2016, 03:16:46 PM »
If they came from the NES, c64, or even systems no 65x based but still low level, then you can probably assume some other things as well; capable of writing their own sprite routines and tilemaps. Not that a quick tutorial or video showing them how to get started would be a waste, because no matter how simple any document appears to describe something, the devil is always in the details. The PCE, not so many devils, but still..

 I toyed with this issue when I was writing tutorials; should I go over 65x basics but use it as more of a stepping board to show how to use the assembler, rather than the architecture of the processor itself. I think it's a good approach, but I never really fleshed it out in the tutorials.

I mean... 8-bit limitations and memory mapping to circumvent address space limitation will not be obvious to modern users, unless they write operating systems.

 If the students in my CS department are any indication (through out the undergrad range), they how no clue how any underlying stuff works. Even the ones that have take the "assembly" required course. In my Java class, they think using a dynamic ArrayList instead of an array, is faster than using an array simply because you don't have to manually copy the references to another array upon expansion. I mean, that's not even low level - it's just out of view. They think some sort of magic is happening behind the scenes, therefore is must be faster or more efficient. If someone from that level is delving into the PCE, and low level, for the first time.. may god have mercy on their soul(tm).

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: The new fork of HuC
« Reply #213 on: December 02, 2016, 03:22:12 PM »
Funny. I remember first starting out on the PCE. Coming from the z80, and also the GB-z80, I couldn't figure out where the damn boot address was in the rom! I asked Dave (Dshadoff) on the ME forums, where it was - and he said it "could be anywhere". I didn't know if he was trolling me or not! I was use boot loader bios pointing to a constant address as the boot for the game code. It took me a week to realize that there was a vector in the rom that pointed to it. That was by far, the biggest hurdle I ever over came on the PCE - to this day. The frustration... ugh. I remember it to this day.

dshadoff

  • Full Member
  • ***
  • Posts: 175
Re: The new fork of HuC
« Reply #214 on: December 02, 2016, 03:43:49 PM »
Funny. I remember first starting out on the PCE. Coming from the z80, and also the GB-z80, I couldn't figure out where the damn boot address was in the rom! I asked Dave (Dshadoff) on the ME forums, where it was - and he said it "could be anywhere". I didn't know if he was trolling me or not!

I honestly don't remember that.
But it wouldn't have been a troll - I try not to do that.  Though, depending on how the question was phrased, we certainly might have misunderstood each other.  (Though since Z-80 also uses a vector, it sounds like we shouldn't have had a communication issue...)
In any case, I'm sorry that I unwittingly contributed to the frustration.
-Dave

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: The new fork of HuC
« Reply #215 on: December 02, 2016, 04:12:57 PM »
Funny. I remember first starting out on the PCE. Coming from the z80, and also the GB-z80, I couldn't figure out where the damn boot address was in the rom! I asked Dave (Dshadoff) on the ME forums, where it was - and he said it "could be anywhere". I didn't know if he was trolling me or not!

I honestly don't remember that.
But it wouldn't have been a troll - I try not to do that.  Though, depending on how the question was phrased, we certainly might have misunderstood each other.  (Though since Z-80 also uses a vector, it sounds like we shouldn't have had a communication issue...)
In any case, I'm sorry that I unwittingly contributed to the frustration.
-Dave

 Well, I didn't know you then.. so I wasn't sure.  :lol: Obviously you weren't a troll and I just probably phrased the question in a weird way. All the z80 systems I worked with had a boot rom where when the rom check passed, it'd jump to a specific rom offset to start user code (I don't remember, but this was a fixed address). I mean, it's not fixed on the z80 or gb-z80, but the bios does jump to a fixed point when the rom checks out/passes. That's what I was looking for on the PCE; a fixed boot address.



 I didn't have any tutorials. While there were some magickit demos, they used library stuff and mkit had terrible documentation in relation to how to use it - I avoided them. So I learned everything from documents, and writing everything from scratch - and there was this really ancient PCE emu with a debugger (it was obscure and japanese; not the PCE one that turned into Ootake. This was a couple of years before that one). Really. crappy. inaccurate. debugger. But it did the job. I was still pretty "new" to assembly, and not too experienced with assemblers. Getting my first h-int code with screen effects working for the first time on PCE, was a pretty amazing feeling. If I managed without tutorials and examples, I'm sure people new to low level can manage just fine with tutorials and examples.

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: The new fork of HuC
« Reply #216 on: December 03, 2016, 01:19:03 PM »
In building them, I had to learn the hard way what was necessary (and why), and it was my way of sharing that hard-fought knowledge.

Hi Dave,

I'm getting more familiar with all the hard work that went into the libraries now that I'm converting them over to the new register convention that I'm trying to implement.

There's a lot of code in there!  8)

May I ask you one quick question?

Do you have any idea of why the libraries keep a reference copy of the VDC registers in RAM in the __vdc array?

It is only done if "HUC" is defined.

Is there some reason that you can think of why the "getvdc" function in huc.asm shouldn't just read the contents of the VDC registers directly?

dshadoff

  • Full Member
  • ***
  • Posts: 175
Re: The new fork of HuC
« Reply #217 on: December 03, 2016, 04:19:12 PM »

Do you have any idea of why the libraries keep a reference copy of the VDC registers in RAM in the __vdc array?

It is only done if "HUC" is defined.

Is there some reason that you can think of why the "getvdc" function in huc.asm shouldn't just read the contents of the VDC registers directly?


If I recall correctly, it's because the registers can't be read from the hardware.
Or at least not all of them can.

If that's not true, then you can probably remove the RAM references safely.

-Dave

TheOldMan

  • Hero Member
  • *****
  • Posts: 958
Re: The new fork of HuC
« Reply #218 on: December 03, 2016, 06:28:03 PM »
Quote
If I recall correctly, it's because the registers can't be read from the hardware.
Or at least not all of them can.

+1. I know the read data can't be (ie,vdc register 2.) Think about how it works.
And, if I remember correctly, most of the others are read only, accordingto the vdc doc in the docs/pce directory.

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: The new fork of HuC
« Reply #219 on: December 04, 2016, 04:03:28 AM »
If I recall correctly, it's because the registers can't be read from the hardware.
Or at least not all of them can.

+1. I know the read data can't be (ie,vdc register 2.) Think about how it works.

Yep, that's true ... but do you actually read these register values?

The only reason that the __vdc array exists is to support reading VDC registers with ...

int a;
 a = vdc[4];


BUT the contents of the array aren't consistently updated when you actually use functions like disp_on()/disp_off()/set_screen_size()/scroll().

It *feels* like it's all left-over from an early version of HuC that was created before the guys started working with the CDROM and making things compatible with how the System Card does things.

So ...


Do you *read* values from the vdc[] array in HuC?

If so, why? What are you trying to achieve?


Do you *write* values to the vdc[] array in HuC?

If so, why? What are you trying to achieve?


Do you use vreg(reg,val) to *write* values to the VDC in HuC?

If so, why? What are you trying to achieve?


BTW ... those questions are for ALL HuC programmers ... I need to know what is important to keep from a compatibility POV, and what I can ditch during spring-cleaning.


And why-oh-why are the register numbers that are passed into these functions double the 16-bit VDC register number (i.e. address in bytes vs. address in words) ... but the VRAM address numbers that are passed into the vram[] array are given (sensibly) as the address-in-words???

Are there #defines for the VDC register names anywhere in HuC ... I can't seem to find them?
« Last Edit: December 04, 2016, 04:15:31 AM by elmer »

dshadoff

  • Full Member
  • ***
  • Posts: 175
Re: The new fork of HuC
« Reply #220 on: December 04, 2016, 03:38:45 PM »
If I recall correctly, it's because the registers can't be read from the hardware.
Or at least not all of them can.

+1. I know the read data can't be (ie,vdc register 2.) Think about how it works.

Yep, that's true ... but do you actually read these register values?

The only reason that the __vdc array exists is to support reading VDC registers with ...

int a;
 a = vdc[4];


BUT the contents of the array aren't consistently updated when you actually use functions like disp_on()/disp_off()/set_screen_size()/scroll().

It *feels* like it's all left-over from an early version of HuC that was created before the guys started working with the CDROM and making things compatible with how the System Card does things.


Well, if you look at the "whats.new" file, you'll see that several layers of changes went in from 3.03 to 3.13.

Sometimes, new things were cleaner - but we couldn't remove the old things because it would break peoples' code.

Around 3.10 to 3.12, it seems that somebody went to the trouble of having direct access to the VRAM registers as though they were an array ( vram[] = val), same as the vdc[] array you mention above.  This wasn't me, so I can't comment much on it.  I wasn't a big fan of arrays because they really can't be made fast on this machine, even if there is some elegance to the idea.


elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: The new fork of HuC
« Reply #221 on: December 05, 2016, 06:42:27 AM »
Sometimes, new things were cleaner - but we couldn't remove the old things because it would break peoples' code.

Since I'm already going to be breaking 100% backwards-compatibility with the change in register assignments, then I think that it's an opporuntity to do some other cleanup.

The idea would be to create a new branch of the project with the changes and so avoid breaking the compatibility that's in my current version of Uli's improvements.

My desire would be to make minimal (if any) changes that would break *current* HuC code usage, but have a little more flexibility with assembly coders (who should be experienced-enough to cope with a few simple changes).


Quote
Around 3.10 to 3.12, it seems that somebody went to the trouble of having direct access to the VRAM registers as though they were an array ( vram[] = val), same as the vdc[] array you mention above.  This wasn't me, so I can't comment much on it.  I wasn't a big fan of arrays because they really can't be made fast on this machine, even if there is some elegance to the idea.

I quite like the idea of the vram array from an "isn't-that-a-clever-idea" POV, but having it as a deliberate function call does make it a bit clearer that there's some underlying cost involved.

There's also the implication that if they are arrays, then you can create a pointer to that array.

IMHO there's not much *reason* that I can really see for keeping either the vdc[] or the vram[] semantics.

At the end-of-the-day, they both just come down to subroutine calls in assembly language, and the duplication of the code (because of the different interfaces) is a bit offensive.

So, if they're not used by current HuC users, then they'll be removed.


*****************

I have another question ...

Does anyone know why there's special-handling for bank $FE in this HuC code?

What is in bank $FE? I've never heard of anything being in that bank before.  :-k

Code: [Select]
; ----
; map_data
; ----
; map data in page 3-4 ($6000-$9FFF)
; ----
; IN :  _BL = data bank
;       _SI = data address
; ----
; OUT:  _BX = old banks
;       _SI = remapped data address
; ----

map_data:       ldx     <__bl

                ; ----
                ; save current bank mapping
                ;
                tma     #3
                sta     <__bl
                tma     #4
                sta     <__bh
                ; --
                cpx     #$FE
                bne     .l1
                ; --
                stx     <__bp
                rts

                ; ----
                ; map new bank
                ;
.l1:            stz     <__bp
                ; --
                txa
                tam     #3
                inc     A
                tam     #4

                ; ----
                ; remap data address to page 3
                ;
                lda     <__si+1
                and     #$1F
                ora     #$60
                sta     <__si+1
                rts

TheOldMan

  • Hero Member
  • *****
  • Posts: 958
Re: The new fork of HuC
« Reply #222 on: December 05, 2016, 07:17:35 AM »
Quote
Does anyone know why there's special-handling for bank $FE in this HuC code?

Not certain about this, by any means, but...
Huc generates a 'hidden' bank for subroutine calls, so that they can be mapped in if required.
I think that may be why HuC subroutines have to be 'call' ed, so they can be mapped in.

I've run into situations where HuC/Pceas will place subroutines from the same file into
different banks. If those routines happen to be all assembler (Yes, I do that), you can't do
a jsr to call the routines. You need to use the HuC call.

Also, I use the vram[] syntax quite a bit for 'quick and dirty' access to sprite/bat information,
especially if I'm using vram as a map. Never used the vdc[] syntax, though.

dshadoff

  • Full Member
  • ***
  • Posts: 175
Re: The new fork of HuC
« Reply #223 on: December 05, 2016, 01:24:28 PM »
I quite like the idea of the vram array from an "isn't-that-a-clever-idea" POV, but having it as a deliberate function call does make it a bit clearer that there's some underlying cost involved.

This was also my opinion.


Quote
I have another question ...

Does anyone know why there's special-handling for bank $FE in this HuC code?

What is in bank $FE? I've never heard of anything being in that bank before.  :-k

Code: [Select]
; ----
; map_data
; ----
; map data in page 3-4 ($6000-$9FFF)
; ----
; IN :  _BL = data bank
;       _SI = data address
; ----
; OUT:  _BX = old banks
;       _SI = remapped data address
; ----

map_data:       ldx     <__bl

                ; ----
                ; save current bank mapping
                ;
                tma     #3
                sta     <__bl
                tma     #4
                sta     <__bh
                ; --
                cpx     #$FE
                bne     .l1
                ; --
                stx     <__bp
                rts

                ; ----
                ; map new bank
                ;
.l1:            stz     <__bp
                ; --
                txa
                tam     #3
                inc     A
                tam     #4

                ; ----
                ; remap data address to page 3
                ;
                lda     <__si+1
                and     #$1F
                ora     #$60
                sta     <__si+1
                rts


Well, looking at that code, I don't think that there's anything special about bank $FE per se.

As the banks are assigned as two sequential banks at the same time, this looks like:
a) an attempt to protect people from mapping the I/O Bank ($FF) as data, and
b) a secret way to get the bank mappings back, without actually changing them.

Again, not my code, so I can't comment any further about specific intent.

Dave

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: The new fork of HuC
« Reply #224 on: December 05, 2016, 02:26:34 PM »
Just another quick question for developers ...

I've rewritten HuC's standard string "strcpy/cmp/..." and "memcpy/cmp/..." to be a bit more respectable for a 6502-platform.

From what I can see, the old HuC didn't actually return the ANSI-standard pointer values from those functions, so I doubt that people are relying on them ... but I thought that I'd better check if anyone was actually looking at the zero-page locations themselves for the pointers.

Now Uli had actually changed the functions to return the ANSI-standard values, which is almost-always just a copy of the original pointer that's passed into the function ... which is great from the POV of standards-compliance, but is absolutely useless in practice (in my experience).

That ANSI definition has annoyed me for decades, so would anyone object if I just have the functions return a pointer to the end of the string/memory, which is something that is actually useful information?  :-k