6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Jun 28, 2024 9:35 pm

All times are UTC




Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Fri Aug 31, 2018 7:21 pm 
Offline

Joined: Tue Jun 19, 2018 8:28 am
Posts: 122
Thank you. It works great.
I was able to advance my project a little bit.
HD44780 library partially works. Screen is initialized and cleared by init() function and I can send characters.
However something weird happens when I try to send entire character string at once. Screen is literally flooded with "6".
Any idea? Code is written in C and quite simple, so for now I ran out of ideas...
Is busy flag checking implemented correctly?

EDIT:

This is weird... This is not about busy flag. I tried to replace with with relatively long delay (50 ms) after writing the byte inside hd44780_putc() function. I was to observe screen being filled with "6". So there must be a problem somewhere inside puts function. I include also compiled version in assembly. Any ideas?

EDIT2:

I also noticed another weird thing. Standard C functions itoa/utoa and sprintf do not work correctly. I try to increment a uint16_t variable in every iteration of the main loop, and then display it on the LCD. itoa/utoa shows "0" for a while ant then "256". Sprintf doesn't show anything ang - program freezes.

Do I need to include something into my program to compile code using those functions?

Code:
#define HD_CMD      (*(uint8_t*)0xA380)
#define HD_DATA      (*(uint8_t*)0xA381)

void hd44780_putc (char c) {
   while (HD_CMD & 0x80);
   HD_DATA = c;
}   

void hd44780_puts (char *str) {
   while (*str) {
      hd44780_putc(*str);
      str++;
   }
}


; ---------------------------------------------------------------
; void __near__ hd44780_puts (__near__ unsigned char *)
; ---------------------------------------------------------------

.segment   "CODE"

.proc   _hd44780_puts: near

.segment   "CODE"

   jsr     pushax
   jmp     L0029
L0027:   jsr     ldax0sp
   sta     ptr1
   stx     ptr1+1
   ldy     #$00
   lda     (ptr1),y
   jsr     _hd44780_putc
   jsr     ldax0sp
   jsr     incax1
   jsr     stax0sp
L0029:   jsr     ldax0sp
   sta     ptr1
   stx     ptr1+1
   ldy     #$00
   lda     (ptr1),y
   bne     L0027
   jmp     incsp2

.endproc



Top
 Profile  
Reply with quote  
PostPosted: Sat Sep 01, 2018 7:18 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1696
Location: Sacramento, CA
Glad to hear the delays worked. I wish I could help more... I did not really dig too deeply into the cc65 sources when I built my libraries. I know I had some issues with the expected position of the stack pointer, so you might check to ensure the stack is not getting corrupted.

Good luck!

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sat Sep 01, 2018 11:25 pm 
Offline

Joined: Tue Jun 19, 2018 8:28 am
Posts: 122
8BIT wrote:
Glad to hear the delays worked. I wish I could help more... I did not really dig too deeply into the cc65 sources when I built my libraries. I know I had some issues with the expected position of the stack pointer, so you might check to ensure the stack is not getting corrupted.l


I don't think so. At this point code is pretty basic - just an I/O drivers and few instructions inside main loop. There is nothing that could possibly exceed available stack.

For now my working hypothesis is that some parts of standard C library are simply not included into version of lib file I've used in my project. I was following these instructions https://cc65.github.io/doc/customizing.html. It was recommended to use simplest one - supervision.lib as a basis, after supplementing it with compiled crt0.s file. So maybe I should use lib file borrowed from other platform? In that case which one should I use? Or maybe it is possible to compile it from source files?

I also have another question. Is it possible to divide my project into two separate EPROM chips? For example leaving main one (32kB) for the main program and ro data, an then placing all I/O routines and library functions inside supplementary chip, for example 8kB?


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 02, 2018 5:29 am 
Offline

Joined: Mon May 25, 2015 1:12 pm
Posts: 92
I'm not saying I know this, because I don't but a quick study suggests that by implicitly specifying output filenames and memory segments in a custom config file, I think you can achieve just that. Good luck and I would love to read about it after.


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 02, 2018 5:32 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1696
Location: Sacramento, CA
Sorry for not being very clear. I was not overrunning the stack, I was causing a misalignment. I'd not leave the stack as I found it... i'd either pull too much off or leave something behind. I hope that makes more sense.

For all my projects, I made a custom library to support the specific I/O for that device. SBC-3 had color graphics, SBC-4 had disk IO. The Kowalski Simulator only had console IO. If you take a look at my source code for those platforms, you can get an idea of the assembly code used to build a new library. The batch files include actually built the libraries from the source for use in your user programs.

I think you can place code in 2 ROMs, you would define two ranges in your ".cfg" file.

I wish I could give you more, but its been several years since I built those and its not as fresh in my mind as it once was. I don't have much free time these days either so my help will be limited.

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 02, 2018 7:08 am 
Offline

Joined: Tue Jun 19, 2018 8:28 am
Posts: 122
8BIT wrote:
Sorry for not being very clear. I was not overrunning the stack, I was causing a misalignment. I'd not leave the stack as I found it... i'd either pull too much off or leave something behind. I hope that makes more sense.


For I try not to use stack in my assembly code. Those are simple i/o routines. Everything else is written in C.
Anyway, I think my initial theory is wrong. I tried to extract sprintf.o and itoa.o files from c64.lib and supervision.lib. In both cases they are exactly the same size.

Is there something else I should do to use standard library, except of including header files in my source code and then giving .lib file to the linker?

UPDATE: I was able to make itoa/utoa work. Kind of... I forgot about placing function prototype inside my source file.
Now function works, but only with 8bit variables. When I try to pass 16bit variable, it doesn't hang my device, but buffer is filled with "256" every single time.

The sprintf function still doesn't work, hanging device completely.

Any ideas? ;)

UPDATE:
Ok, I have yet another hypothesis. I've noticed that Watara Supervision was a handheld console using CMOS version of 6502. Currently I am using original, NMOS version of this CPU. Probably new instructions from compiled version of standard library are the reason of this unstability. Any idea which library should I "borrow" instead?

UPDATE:
Hypothesis confirmed. It works with c64.lib.


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 10, 2018 11:33 am 
Offline

Joined: Tue Jun 19, 2018 8:28 am
Posts: 122
Yet another question:
How to add a MEMORY {} and SEGMENTS {} configuration for non volatile EEPROM memory? I am going to use AT28C64B, to store configuration. How to define a structure to place it inside EEPROM address space?


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 10, 2018 7:36 pm 
Offline

Joined: Mon May 25, 2015 1:12 pm
Posts: 92
I added all the bits that are in the EEPROM's address range, specified that the empty bits be filled and directed the ROM bits to the O%. Oh and the bits in the O% are specified as ro (read only) I hope that this helps. My .cfg file is attached for reference with the wrong file extension as it wouldn't go otherwise.


Attachments:
hb_comp.txt [1.06 KiB]
Downloaded 114 times
Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 11, 2018 5:42 am 
Offline

Joined: Tue Jun 19, 2018 8:28 am
Posts: 122
I had something a little bit different in mind. Simply speaking I'd like to define another segment pointing to the EEPROM memory, and then instruct program to place some variables there. Something like EEMEM or PROGMEM from AVR microcontrollers. Of course such variables would have to be global to occupy the same memory fragment all the time and could not be initialized with a value, to prevent old setting being wiped out.

Is it possible to do something like that?


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 11, 2018 5:49 am 
Offline

Joined: Mon May 25, 2015 1:12 pm
Posts: 92
I see, well then. There's no proper mechanism that I'm aware of from within cc65. You could creste a bunch of variables in a custom defined segment and use pointers however. I'm sure that'd work. OTOH, I may have missed something and hope the brains trust proves me wrong. As far as I'm aware, variables that are constant or defined at compile time are copied over to RAM at startup.


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 11, 2018 6:30 am 
Offline

Joined: Tue Jun 19, 2018 8:28 am
Posts: 122
DigitalDunc wrote:
I see, well then. There's no proper mechanism that I'm aware of from within cc65. You could creste a bunch of variables in a custom defined segment and use pointers however. I'm sure that'd work. OTOH, I may have missed something and hope the brains trust proves me wrong. As far as I'm aware, variables that are constant or defined at compile time are copied over to RAM at startup.


Then I assume best closest solution will be to simply define a structure type, holding my settings:

Code:
typedef struct {
   uint8_t setting1;
   uint16_t setting2;
} cfg_t


And then define pointer to memory residing inside EEPROM space:

Code:
#define Config (*(cfg_t*)0x2100)


The main drawback of that solution is a requirement of manual address calculation, to avoid data structures overlapping.


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 11, 2018 2:14 pm 
Offline

Joined: Mon May 25, 2015 1:12 pm
Posts: 92
Yes, but if you define the type in the main program then you can create a pointer of that type and as long as the base address is correct, any indexes will offset by the relevant amount.


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 16, 2018 2:20 pm 
Offline

Joined: Tue Jun 19, 2018 8:28 am
Posts: 122
8BIT wrote:
I can help, but I need to know the clock frequency of your system. Also note, the _delay_3us routine will use a minimum of 12 cycles, not including the JSR used to call it. So if you are using a 1 MHz clock, you may want to consider a 20us delay routine. Anything under that can be done with NOP or other code inline.


Thank you for your help with delay loops once again. ;)
Currently I am modifying my hardware, by replacing classic 1MHz MOS6502 with WDC65C02, running at 4 MHz.
Can you help me with a suitable modification of your delay routines? I assume it won't be possible to do it by just scaling up a value passed to the routines by the registers, because of their limited size. What do do then? Placing additional NOPs inside the loop? Using completely different approach? I know my question is basic, but I have no experience with assembly and performing own experiments would be extremely time consuming, due to necessity of erasing EPROM every time.


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 16, 2018 8:36 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1696
Location: Sacramento, CA
Try this for a 4MHz clock:

Code:
; ---------------------------------------------------------------------------
; Delay's based on 4MHz 65C02 CPU
;
; Delay 4us
; there's an additional 3us overhead for each call, so the
; minimum delay is 7us with increments of 4us. The formula is:
; duration = 4*a + 3, where "a" is the value in the accumulator
; note a value of zero in "a" is treated as 256, not zero!
; range is from 7us to 1027us

_delay_4us:      ; 6 jsr
   tax         ; 2
delay_4us_loop:
   pha         ; 3
   pla         ; 4
   nop         ; 2
   nop         ; 2
   dex         ; 2
   bne delay_4us_loop    ; 2/3
   rts         ; 6

; ---------------------------------------------------------------------------
; Delay ms
;
_delay_ms:
   tay
   lda #249                            ; 249*4 + 3 = 999
delay_ms_loop1:   
   jsr _delay_4us
   dey
   bne delay_ms_loop1
   rts


Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: