6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 5:41 pm

All times are UTC




Post new topic Reply to topic  [ 217 posts ]  Go to page Previous  1 ... 10, 11, 12, 13, 14, 15  Next
Author Message
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 5:35 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3346
Location: Ontario, Canada
Hugh Aguilar wrote:
Okay, my math was screwed up badly. Your calculation seems to be correct.
If each cylinder fires 50 times per second then won't the total for all eight cylinders be 400 firings/sec, or 2.5 ms between firings? (There's a factor-of-two difference to account for the engine being four-stroke. Perhaps BDD inadvertently included that step twice.)

And, re: BRK and re: (direct,X) address mode, I echo Garth's responses: never, and all the time.

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 5:52 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
Hugh Aguilar wrote:
On this subject, does anybody actually use BRK for anything?

Every 65xx system for which I have written software (starting with a locomotive event recorder in the 1970s) has made use of the BRK instruction in one way or another. It is common practice with many machine language monitors running on 65xx systems to wedge themselves into the IRQ/BRK handler so that the monitor will get control if the MPU executes BRK. When that happens, the monitor will usually dump the registers and await user input. Once stopped, the programmer can examine memory, patch code if necessary, and then restart the program. During software development I insert a macro named BREAK into the source code at potential trouble spots precisely for this purpose.

Another application for BRK, as Garth noted, is in an operating environment whose APIs are called via a software interrupt. BRK is the only software interrupt available with the 65C02.

Quote:
Another possibility is to get rid of decimal mode, which almost nobody uses, which would simplify the processor and also free up the D-flag.

Decimal mode is useful for converting from binary to ASCII for display purposes. In some cases, an operating system may maintain the time-of-day (TOD) in BCD format, since it is readily convertible to ASCII with succinct code. In such a case, it is likely the code that maintains the TOD "registers" would have to be able to perform decimal arithmetic.

Although not as likely, there may be software in which arithmetic is performed in BCD in order to avoid the errors that may occur in floating point binary during conversion from ASCII. Back when I did professional development for the Commodore 128 all values that represented money were stored in BCD format and computations were carried out with the MPU in decimal mode.

Quote:
There is actually a lot of cruft in the 65c02 that could be discarded. I already mentioned the (direct,X) addressing-mode, which almost nobody uses. There is not very much legacy 65c02 code around that anybody cares about, so strict compatibility with the 65c02 may not be very important.

I suspect Bill Mensch, Jr. would take issue with the "cruft" characterization. :D

Just so you know, the UART driver running in my POC V1.1 unit and soon to be running in POC V2 make extensive use of that crufty indexed indirect addressing mode. Forth implementations likewise extensively use that addressing mode to manipulate the data stack if it is set up on zero page. Here's an excerpt from the POC V2.1 UART driver so you can see how often (<dp>,X) is being used:

Code:
;—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—
;
;vQUART RECEIVER IRQ PROCESSING
;
iirq0200 lda #n_nxpchn-1       ;starting channel
;
;
;   channel processing loop...
;
.0000010 pha                   ;save channel index
         asl                   ;channel pointer offset
         tax
         lda (tiaisr,x)        ;get IRQ status **********
         bit nxprqtab,x        ;RxD interrupting?
         beq .0000030          ;no, skip this channel
;
         lda #nxpcresr         ;clear any...
         sta (tiacr,x)         ;RxD overrun error **********
;
;
;   FIFO processing loop...
;
.0000020 lda (tiasr,x)         ;get channel status **********
         bit #nxprxdr          ;RxD FIFO empty?
         beq .0000030          ;yes, done with channel
;
         lda (tiafif,x)        ;get datum **********
         xba                   ;protect it
         lda tiaputrx,x        ;get CFIFO 'put' pointer
         ina                   ;bump it &...
         and #m_fifwrp         ;wrap to CFIFO boundary
         cmp tiagetrx,x        ;any room in CFIFO?
         beq .0000020          ;no, discard datum
;
         xba                   ;expose & store...
         sta (tiaputrx,x)      ;datum in CFIFO **********
         xba                   ;expose & save...
         sta tiaputrx,x        ;'put' pointer
         bra .0000020          ;loop
;
;   ...end of FIFO processing loop
;
.0000030 pla                   ;get channel index
         dea                   ;all channels serviced?
         bpl .0000010          ;no
;
;   ...end of channel processing loop
;
;—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—
;
;vQUART TRANSMITTER IRQ PROCESSING
;
iirq0300 lda #n_nxpchn-1       ;starting channel
;
;
;   channel processing loop...
;
.0000010 pha                   ;save channel index
         asl                   ;channel pointer offset
         tax
         lda (tiaisr,x)        ;get IRQ status **********
         bit nxptqtab,x        ;TxD interrupting?
         beq .0000040          ;no, skip this channel
;
         lda tiagettx,x        ;yes, load 'get' pointer
;
;
;   FIFO processing loop...
;
.0000020 cmp tiaputtx,x        ;any data in CFIFO?
         beq .0000030          ;no, kill transmitter
;
         tay                   ;protect 'get' pointer
         lda (tiasr,x)         ;get channel status **********
         bit #nxptxdr          ;TxD FIFO full?
         beq .0000040          ;yes, done for now
;
         lda (tiagettx,x)      ;read CFIFO &... **********
         sta (tiafif,x)        ;write to TxD FIFO **********
         tya                   ;recover 'get' pointer
         ina                   ;bump it &...
         and #m_fifwrp         ;wrap to CFIFO boundary
         sta tiagettx,x        ;update 'get' pointer
         bra .0000020          ;loop
;
;   ...end of FIFO processing loop
;
.0000030 lda #nxpcrtxd         ;disable...
         sta (tiacr,x)         ;transmitter **********
         lda tiatstab,x        ;tell foreground...
         tsb tiatxst           ;about it
;
.0000040 pla                   ;get channel index
         dea                   ;all channels serviced?
         bpl .0000010          ;no
;
;   ...end of channel processing loop

I flagged the lines where (<dp>,X) addressing is used with **********. The above code drives four receivers and four transmitters and is expandable to many more channels without adding a single line of code.

Quote:
I still don't know of any reason why transferring files in and out of a desktop computer has to be done quickly --- this is not real time --- also, the maximum memory is 16MB, so even at fairly slow speeds there isn't going to be a noticeable delay.

Assuming the (serial) data link is running at 115.2Kbps, with 8N1 data format, the data rate on the wire would be 11,520 bytes per second. At that speed, it would take more than 24 minutes to transfer 16MB of data, assuming 100 percent error-free transmission. If your next task after starting the data transfer is to use that data on the destination system you will be twiddling your thumbs for 24 minutes waiting for the transfer to complete. Adding to the fun, many such transfers are not raw binary, but use Intel or Motorola hex ASCII in the data stream, which means the effective transfer rate will be much slower, since less information will be carried per byte transferred.

So, yes, it is very much a real time situation.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 6:13 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
Dr Jefyll wrote:
Hugh Aguilar wrote:
Okay, my math was screwed up badly. Your calculation seems to be correct.
If each cylinder fires 50 times per second then won't the total for all eight cylinders be 400 firings/sec, or 2.5 ms between firings? (There's a factor-of-two difference to account for the engine being four-stroke. Perhaps BDD inadvertently included that step twice.)

Oops! :oops: I was using the calculator in Windows and I think I accidentally hit Enter twice at the end to get the answer. Ugh! The math itself is simple enough, but who knows what you'll get when a ham-fisted operator is at the keyboard. :evil: I fixed the earlier post.

Quote:
And, re: BRK and re: (direct,X) address mode, I echo Garth's responses: never, and all the time.

BRK gets a lot of use around here. :D POC's firmware, which includes Supermon 816, by default routes a BRK to the monitor's entry point. That can be changed by modifying a vector.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 6:21 am 
Offline

Joined: Fri Jun 03, 2016 3:42 am
Posts: 158
GARTHWILSON wrote:
Hugh Aguilar wrote:
With a lot of I/O it would help to have multiple interrupts. The 65c02 or 65c816 would have a problem because they only have the IRQ and NMI, so each interrupt has to poll a lot of I/O ports to figure out what tripped the interrupt. The 65VM02 has MIRQ3, MIRQ2, MIRQ1, MIRQ0, IRQ, and NMI. This is still not enough.

I think the spark timing is the only thing that has to be pretty accurate in terms of microseconds. Engine speed and load aren't going to change significantly in 10ms, let alone 10µs, so valve timing would be maintained mechanically after the computer dictates what it should be for the next so many revolutions, as would be the case for the mixture; and temperature sensors won't respond to millisecond changes anyway. I don't have any idea how quickly oxygen sensors respond. The slow stuff can all be polled, not requiring interrupts. For the ignition timing, it is critical for the computer to know the shaft position though, and some sort of resolver-to-digital converter, or shaft position sensor, would probably have to be interrupting the processor at a furious rate. A possible alternative would be that the ignition timing is taken care of in a separate circuit (possibly even a microcontroller's module that's not part of the processor itself), where the processor gives it a shaft offset angle telling it when to fire, so the processor doesn't need to "bit-bang" it. In that sense it would be like the processor sending a UART a byte and then going away to do something else while the UART takes care of the timing.

I agree that all of this stuff is very slow, in the several millisecond range.
Only ignition timing needs to be accurate.
In the current design (without a coprocessor) I have the MIRQx interrupts whose ISRs can be interrupted by IRQ and NMI --- so IRQ or NMI would be tied to a timer that does the ignition and has to be accurate --- the MIRQx would be used for various low-priority interrupts.

GARTHWILSON wrote:
Quote:
On this subject, does anybody actually use BRK for anything?

I haven't used it since my 6502 class in 1982, and my ISRs never waste time checking for it. Some programmers have used it in multitasking operating systems though.

In my 65c02 cross-compiler, I used BRK for single-step debugging. The Forth compiler would compile a BRK between each Forth word. It also maintained an association on the host computer that associated the address of each BRK in the machine-code with the corresponding location in the source-code. When the BRK occurred, the 65c02 would send all the pertinent information (register contents, data-stack contents, return-stack contents) to the host computer over the RS232. The host computer would display the source-code with a flashing smiley-face at the location of the break (Forth source-code is space-delimited, so the smiley-face would be between words), and it would also show the pertinent information along the bottom of the screen. It would do a QUERY INTERPRET so the user (I was the only person who ever used the system) could do some interactive debugging. I could query the 65c02 on such things as the contents of variables, etc.. I could also just hit the <RETURN> key to keep going. I could also write code that checked something, like a variable changing, and didn't stop the system with QUERY INTERPRET until this happened. My debugger was loosely modeled after Borland Turbo Debugger for the 8086 that I was familiar with, and it did everything that debugger did, but somewhat slower (the 19,200 baud rate was what was dragging the speed down).

That is the only time that I have used BRK for anything. I don't think source-level single-stepping is all that useful now --- I was somewhat of a novice at Forth in those days --- I wouldn't do that now.

For the most part, I think the 65VM02 should be 65c02 compatible. I will keep clunky features such as (direct,X) addressing and decimal mode even though I don't use them myself. I think though, that I could get rid of BRK and nobody would ever care --- that is a very clunky feature! --- having another level of interrupts above MIRQ would be pretty useful.

BTW: I'm considering adding PHM and PLM instructions to push and pull the contents of a direct memory variable without using a register.

For example, this is what I currently have:
Code:
ENTER:
    LDY lf
    PHY             ; push parent's LF to the return-stack under our locals
    LLY
    STY lf          ; set LF to our local frame
    NEXT

LEAVE:              ; this is used instead of EXIT if ENTER was done (if the function had local variables)
    PLY
    STY lf          ; restore the parent's LF that was pushed in ENTER
    OPA             ; the operand is the size of our local variables (not counting the pointer to the parent's local frame)
    AAS             ; discard our local variables
    ; falls through
WEXIT:              ; this exits a function (a "word" in Forth terminology)
    PLY
    PLA
    EXIP            ; restore the old IP that was pushed in CALL or EXECUTE
    NEXT

This is what I would do instead:
Code:
ENTER:
    PHM lf         ; push parent's LF to the return-stack under our locals
    LLY
    STY lf          ; set LF to our local frame
    NEXT

LEAVE:              ; this is used instead of EXIT if ENTER was done (if the function had local variables)
    PLM lf          ; restore the parent's LF that was pushed in ENTER
    OPA             ; the operand is the size of our local variables (not counting the pointer to the parent's local frame)
    AAS             ; discard our local variables
    ; falls through
WEXIT:              ; this exits a function (a "word" in Forth terminology)
    PLY
    PLA
    EXIP            ; restore the old IP that was pushed in CALL or EXECUTE
    NEXT


This would speed up ENTER and LEAVE slightly. Do you think that PHM and PLM would have any general-purpose use? They seem like they might be useful, especially if A and Y are already being used for other purposes, but I can't think of any specific case in which they would be needed.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 6:36 am 
Offline

Joined: Fri Jun 03, 2016 3:42 am
Posts: 158
Dr Jefyll wrote:
Hugh Aguilar wrote:
Okay, my math was screwed up badly. Your calculation seems to be correct.
If each cylinder fires 50 times per second then won't the total for all eight cylinders be 400 firings/sec, or 2.5 ms between firings? (There's a factor-of-two difference to account for the engine being four-stroke. Perhaps BDD inadvertently included that step twice.)

Actually, I got 2.5 milliseconds also, but then I was unsure of myself and thought I had screwed up yet again. Tomorrow I will give some more thought to the subject, and also review how a four-stroke engine works, but it is midnight right now and I can't think straight for such calculations.

Dr Jefyll wrote:
And, re: BRK and re: (direct,X) address mode, I echo Garth's responses: never, and all the time.

Well, I have found (direct,X) to be useless. This was because you have a table of pointers to byte data. It would be much more useful if you had a table of pointers to cell (two byte) data --- you do on the 65c816, so I suspect this is used a lot on the 65c816 --- but on the 65c02 and 65VM02 you only have byte data, which is not very useful. I will leave it in though! Maintaining 65c02 compatibility is worthwhile.

I think that I could get rid of BRK though, and nobody would care. The few times that it is used, it is by systems software (my source-level single-step debugger was systems software) rather than by application programs. The 65VM02 is going to have a multi-tasking OS though (that is the one of the main features), so systems software would be done as part of the OS. Also, as I said, I no longer believe that a source-level single-step debugger is particularly useful. Nowadays, I program Forth in a more traditional manner --- I rely on interactive testing of colon words at the command-line --- also, a debugger isn't going to work with real-time code, which is the whole point of a micro-controller.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 7:00 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
Hugh Aguilar wrote:
Only ignition timing needs to be accurate.

Not so! Fuel injection timing must be equally accurate, as all modern systems inject fuel only during a precisely delineated portion of the intake stroke. There are two components to this: the point relative to the start of the intake stroke when injection is to commence and the duration of the injection. These two factors, along with injector design, determine how much fuel gets injected. As a gasoline engine should ideally be run with a stoichiometric air-fuel ratio to assure total combustion, injection timing is one of the most critical factors in getting best engine performance.¹

Something that complicates the achievement of stoichiometry is the inertia of fluids, which means that the onset of fuel delivery into the intake air stream does not instantly occur when the injector is commanded by the control circuitry to commence injection. This lag is a constant that is determined by the injector design and condition, whereas the interval during which injection must happen is constantly changing as the throttle opening, engine speed and loading vary, further affected by other variables, such as air density and in some cases, the fuel's octane rating. In general, the control circuitry has to start the injection sequence earlier at higher engine speeds in order to compensate for injection lag. If the engine is running at full throttle injection has to start sooner than at part throttle. In all cases, injection must cease before the intake valve closes, as any fuel injected after valve closure will be added to the fuel charge on the next intake stroke, causing the cylinder to run rich. The relationships are complex and the system activity required to achieve stoichiometry is considerable.

Of all the control subsystems in modern cars, fuel delivery control is usually the most complex and demands the most accurate timing. Things have certainly come a long way since the days of the constant-flow injection systems that were developed for race cars and aircraft in the 1930s. :D

———————————————————————————————————
¹In modern cars when being driven at part throttle, the engine is run leaner than stoichiometric as a fuel economy measure. Doing so has emissions implications, however, as combustion temperatures are higher, which encourages the formation of oxides of nitrogen. Also, the higher combustion temperatures can adversely affect engine life.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 7:47 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
Hugh Aguilar wrote:
Well, I have found (direct,X) to be useless.

You can't generalize something like that solely from your experience. The folks who make microprocessors, where resource consumption (i.e., die space) is a major factor in which features get included and which features get left out, are not going to design in a feature that is useless. In other words, it is HIGHLY unlikely the designers of the 6502 (Bill Mensch, Chuck Peddle, et al) would have consumed valuable die real estate adding a useless addressing mode to all of the primary accumulator instructions.

Quote:
This was because you have a table of pointers to byte data. It would be much more useful if you had a table of pointers to cell (two byte) data...

I was fortunate to be around when the 6502 was the new kid on the microprocessor block, which means I have first-hand familiarity with the 6502's original purpose in life (aside from stealing business from Motorola), which was industrial control applications, not general purpose computers. I wrote my first 6502 program to run on a locomotive event recorder, which was a data acquisition device that was intended to serve a purpose similar to that of the flight data recorder in an airliner. Nowadays, such a device would be a microcontroller with a bunch of inputs and some non-volatile RAM in which to store acquired data and working variables. Back then, one had to build the equivalent of a microcontroller from discrete parts.

As I became familiar with the 6502, it was soon patent that the (<dp>,X) addressing mode was tailor-made for accessing I/O devices, using a very simple indexing algorithm. In the application for which I was programming, there was plenty of zero page space available, since there was no operating system in a form which we would recognize now. So I liberally used (<dp>,X) in my code, which made it easy to say (in effect) "read input number 4" without a lot of code. That, in turn, made it possible to keep the firmware succinct, a critical concern in a system with only 2K of ROM (specifically, PROM, which was expensive and slow to program).

When Forth first started to be used on 6502 hardware it is likely the person(s) writing the kernel immediately saw the value of using (<dp>,X) to manage a zero page data stack. I had no knowledge whatsoever of Forth in those days (and cheerfully admit I still don't have much knowledge of Forth) but I can well envision what a clever Forth kernel developer must have thought as s/he was studying the 6502 instruction set and encountered the indexed indirect addressing mode instructions. Naturally, a 65C816-based Forth can use (<dp>,X) more efficiently, since a word can be loaded/stored without extra addressing acrobatics. However, that doesn't relegate (<dp>,X) solely to the '816.

With my POC design, I am using (<dp>,X) in the manner most likely envisioned by the original 6502 designers, which is addressing device registers. (<dp>,X) addressing allows me to write succinct routines for servicing the virtual QUART (vQUART) in POC V2.1, in which a total of 14 device registers must be accessed during run-time. Along with that, I use (<dp>,X) addressing to read and write the circular FIFOs associated with the vQUART, using a single channel index number. This is a form of hardware abstraction that (<dp>,X) addressing is uniquely suited to implementing.

So before you dismiss what are to you "useless" features you should consider that your view of how the 65C02 has been used and is currently being used is a narrow one. Having worked professionally with 6502 hardware for some 40 years, during which time I've written hundreds of thousands of lines of assembly language, I have a much more expansive view of how the '02 is and can be used.

Quote:
I think that I could get rid of BRK though...I rely on interactive testing of colon words at the command-line...

Not everyone is into Forth, you know. Are you designing something that will only work well with Forth or are you hoping to produce a general purpose design that isn't married to a specific environment?

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 9:02 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
Replying to lots of things on this page (13), without quoting:

We used BRK to get back to the monitor on the AIM-65's we used in the 6502 class in 1982. Five years later in a work project, I did the other functions talked about with JSR BREAK, and BREAK let me see the address, the contents of all the registers, peek around, modify things, etc., and then pick back up at the instruction following the JSR BREAK. Not using BRK made the ISR faster, not having to check the B bit.

Accuracy in the cents in financial calculations can be had in hex by internally representing the cent as 1 and the dollar as 100 (or $64), rather than trying to represent the cent as .01 (which is something like .00000010100011110101...b) and the dollar as 1. We do this kind of thing in scaled-integer math all the time. In that sense, you could even represent one-third perfectly, by representing it as 1 (or 4 or some other integer), and representing 1 as three times as many as 1/3. That's not to say the 6502's decimal mode isn't useful, but I haven't used it in decades (except to write this HTD article in the source-code repository).

As for PHM and PLM: PHM sounds like pretty much the same thing the 816's PEI instruction does, although there's no complementary pull instruction.

In Forth, (ZP,X) is used to point to memory locations whose addresses are on the data stack, since the programmer won't know ahead of time where the top of the stack will be when the particular code is run. Storing, retrieving, or RMW instructions to locations whose addresses are on the data stack are all game. X is the stack pointer.

The cars I've seen the fuel injection on used one sprayer for all the cylinders, and it sprayed continually. The computer told it how heavily to spray; but it did not turn off between intake strokes. I can imagine a reason to have a sprayer for each cylinder, but I think you'd want to have it far enough upstream to give the fuel more time to evaporate, and you wouldn't want the intake air to be "striped." :lol:

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 2:51 pm 
Offline

Joined: Fri Jun 03, 2016 3:42 am
Posts: 158
GARTHWILSON wrote:
Replying to lots of things on this page (13), without quoting:

We used BRK to get back to the monitor on the AIM-65's we used in the 6502 class in 1982. Five years later in a work project, I did the other functions talked about with JSR BREAK, and BREAK let me see the address, the contents of all the registers, peek around, modify things, etc., and then pick back up at the instruction following the JSR BREAK. Not using BRK made the ISR faster, not having to check the B bit.

BRK is only used in systems' software, and this would be written within the context of the multi-tasking OS on the 65VM02. I think BRK can be discarded.

I used BRK in my debugger, and it really bloated out the code a lot. If I had used JSR BREAK instead, the bloat would have been considerably worse. So this is an argument for BRK. This argument only makes sense in regard to an STC (subroutine-threaded code) Forth system. In a byte-code VM you would just have a primitive BREAK that the compiler compiles as needed. The whole idea of the 65VM02 is to run a VM (hence the name), so I don't anticipate anybody generating machine-code --- or, at least, if they do, then this would be pretty minimal, such as an optimizing compiler that generates new primitives on the fly --- if they want a single-step debugger (C programmer's usually do) then they won't be doing BRK inside of primitives, but they will just use a BREAK primitive as described above.

So, BRK can be discarded. Everything else in the 65c02 will be kept for compatibility however.

GARTHWILSON wrote:
In Forth, (ZP,X) is used to point to memory locations whose addresses are on the data stack, since the programmer won't know ahead of time where the top of the stack will be when the particular code is run. Storing, retrieving, or RMW instructions to locations whose addresses are on the data stack are all game. X is the stack pointer.

In my current design, I am assuming that a split-stack is used. This means that you have one stack for low bytes and one stack for high bytes, both indexed by X (I got this idea from ISYS Forth on the Apple-IIc that my cross-compiler was compatible with). The advantage here is that only one INX is needed to drop a 16-bit value from the data-stack, and one DEX to make room for a new 16-bit value.

I'm thinking now however, that I might change this and go with a combined stack in which the low and high byte are juxtaposed. This would involve adding these instructions:
Code:
DINX                add 2 to X          effectively the same as: INX INX
DDEX                subtract 2 from X   effectively the same as: DEX DEX
LDYA direct         load YA from the direct-page variable
LDYA (direct,X)     load YA indirectly from an array of direct-page pointers indexed by X
STYA direct         store YA to the direct-page variable
STYA (direct,X)     store YA indirectly to an array of direct-page pointers indexed by X

This would actually be a lot more efficient. I was looking at my code and I was not happy with having to do this at the front of almost every primitive:
Code:
    LDY toslo,X
    LDA toshi,X

I'm pretty dubious of adding PHM and PLM as I mentioned previously. I can't think of any use for these other than ENTER and LEAVE --- nobody has mentioned any use that they know of.

A better idea is to introduce a new register called F that holds the local-frame pointer, rather than use the LF direct-page pointer. This involves adding a raft of new instructions though, which complicates the processor a lot. Whether this is worthwhile or not, depends upon how much local variables are used. In Forth, a lot of functions don't have local variables at all, but only use the data-stack. In C, Pascal, etc., the functions only use local variables and don't have a data-stack, so the F register would be hugely helpful to speeding up these languages.

I will give some further thought to these matters and come up with a new version of the document pretty soon.

GARTHWILSON wrote:
The cars I've seen the fuel injection on used one sprayer for all the cylinders, and it sprayed continually. The computer told it how heavily to spray; but it did not turn off between intake strokes. I can imagine a reason to have a sprayer for each cylinder, but I think you'd want to have it far enough upstream to give the fuel more time to evaporate, and you wouldn't want the intake air to be "striped." :lol:

Well, fuel injection means you have a "sprayer" for every cylinder. Ye olde carburetor was a sprayer for all the cylinders.

I think Garth is correct though, that the only accurate timing that needs to be done is of the ignition. You can't actually turn a sprayer on and off rapidly due to physical limitations of valves, which are large mechanical contraptions.

I admit that I'm not an auto mechanic though.

My previous calculation of how many ignitions you have was totally screwed up. I figured it out though:
Code:
M = maximum revolutions per minute
C = cylinders
T = time in microseconds between ignitions

T= 1E6 / (M/60)*(C/2)

So, for an 8 cylinder engine at 6000 rpm, we have 2,500 microseconds, or 2.5 milliseconds.

This is pretty pedestrian. A 25 Mhz. 65VM02 is far more than fast enough for this.

The 2 Mhz. 65c02 is plenty fast enough for this. The reason a 65c02 isn't a realistic choice, is because it only has IRQ and NMI and hence each ISR has to poll the I/O to figure out what tripped the interrupt. Modern processors, including the 65VM02, have a lot of interrupts though.

I still don't know why a PowerPC/eTPU is needed --- that is a hugely powerful computer (significantly more powerful than the desktop computers of the early 1990s) --- maybe car manufacturers are just a conservative lot who feel more comfortable with a big powerful computer so there is no danger whatsoever of lacking enough computer power to do everything that anybody may ever think of needing.

As I said before, maybe the 65VM02 would be used by Yugo for their next cheapo gas-guzzler that is unsafe at any speed --- they actually used cardboard for the interior paneling --- within that context, they might consider the 65VM02 to be right up their alley!

As for NASA, they might consider the 65VM02 also --- I would expect it to use less power than the RTX2010 that they currently use --- but I don't care if NASA uses it or not, because there is no money is supporting onesy/twosy projects.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 3:44 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
GARTHWILSON wrote:
The cars I've seen the fuel injection on used one sprayer for all the cylinders, and it sprayed continually. The computer told it how heavily to spray; but it did not turn off between intake strokes. I can imagine a reason to have a sprayer for each cylinder, but I think you'd want to have it far enough upstream to give the fuel more time to evaporate, and you wouldn't want the intake air to be "striped." :lol:

You must have been looking at 1980s fuel injection technology, which is when constant-flow injection was around (back then, we referred to General Motors' throttle body fule injection, which was a constant flow system, as a "leaky carburetor"). Every new car sold in North America since the latter 1980s has used timed injection, in which the injectors (one per cylinder) discharge fuel only during the intake stroke. Injectors typically discharge directly into the intake port, not the manifold, except in a few cases, in which the injector discharges into the manifold runner very close to the cylinder head. These design features exist primarily to reduce exhaust emissions, although the direct port injection setup does tend to produce more horsepower at full throttle.

Timed injection is not new. Mercedes-Benz had it in their 1940s cars and Daimler-built aircraft engines used in such World War II combat aircraft as the ME-109 had it as well.

Hugh Aguilar wrote:
I think Garth is correct though, that the only accurate timing that needs to be done is of the ignition. You can't actually turn a sprayer on and off rapidly due to physical limitations of valves, which are large mechanical contraptions.

I admit that I'm not an auto mechanic though.

That you're not an auto mechanic is apparent. :D

Unless you are driving a 30 year old car, the "sprayers" (correctly called "injectors") in your vehicle are indeed cycled at the same rate as the cylinders are firing. At 6000 RPM (to use an earlier example), each injector is cycled 50 times per second, which is once every 20 milliseconds. Automotive fuel injectors are not "large mechanical contraptions"—they are actually rather small and are electrically controlled. You must be thinking of the fuel injectors used in large Diesel engines, which are also cycled at the same rate at which the cylinders fire.

Quote:
In my current design, I am assuming that a split-stack is used. This means that you have one stack for low bytes and one stack for high bytes, both indexed by X (I got this idea from ISYS Forth on the Apple-IIc that my cross-compiler was compatible with). The advantage here is that only one INX is needed to drop a 16-bit value from the data-stack, and one DEX to make room for a new 16-bit value.

So much for the idea of the 65VM02 being generally useful. You're basically designing a Forth-specific processor.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 4:45 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1927
Location: Sacramento, CA, USA
BigDumbDinosaur wrote:
... So much for the idea of the 65VM02 being generally useful. You're basically designing a Forth-specific processor.

Now we just need to convince everyone that Forth is generally useful, and all is once again right in the universe. :D

BDD, you have given the best testimony so far regarding the complexity of modern computerized engine management, but your descriptions still fail to provide a complete picture of the demands.

https://en.wikipedia.org/wiki/Engine_control_unit

The required on-board diagnostic executives can be quite complex, and the network packet manager has some hard real-time requirements (for stability control and other occupant safety features that are now also required).

GARTH WILSON wrote:
The cars I've seen the fuel injection on used one sprayer for all the cylinders, and it sprayed continually. The computer told it how heavily to spray; but it did not turn off between intake strokes.


I am not familiar with any system that operates the way you describe. I certainly haven't seen it all, but I have seen a lot in my 33 years of working on cars and trucks for a living.

Mike B.


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 5:33 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
Hugh Aguilar wrote:
On this subject, does anybody actually use BRK for anything?

Acorn's BBC Basic uses BRK for error conditions: the BRK is followed by an error code byte and then a human-intelligible message. This version of Basic does have an ON ERROR mechanism, so it's not the case that Basic has to reset its state entirely, but it does abandon the current line and current program flow. (Any language or application on this machine installs a BRK handler, so it can use BRK for whatever purpose it likes.)


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 6:17 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
barrym95838 wrote:
BigDumbDinosaur wrote:
... So much for the idea of the 65VM02 being generally useful. You're basically designing a Forth-specific processor.

Now we just need to convince everyone that Forth is generally useful, and all is once again right in the universe. :D

You'll never convince me. :D

Quote:
BDD, you have given the best testimony so far regarding the complexity of modern computerized engine management, but your descriptions still fail to provide a complete picture of the demands...

It's hard to present a complete picture of the complexity and the (often-competing) demands of modern engine management without writing a book about it.

Quote:
The required on-board diagnostic executives can be quite complex, and the network packet manager has some hard real-time requirements (for stability control and other occupant safety features that are now also required).

Mention of the vehicle "network," which is more akin to an interface bus, is interesting.

An automobile is an electrically "dirty" environment, with lots of EMI being generated by the ignition system, hash being generated on the 12 volt circuits by the alternator, flyback impulses being kicked out by relay and solenoid coils, etc. Hence the data bus that interfaces all this stuff has to be much more robust than usual. Most vehicle data buses are either TIA-422 or TIA-485, as these are low impedance, balanced to ground and are operated with relatively large voltage swings, giving them good noise immunity. It was in this area that Philips Electronics did a lot of work to get reliable operation in a vehicle. The NXP "impact" line of UARTs (such as the 28L92 I use in my POC units) are the most popular for this sort of application.

Quote:
GARTH WILSON wrote:
The cars I've seen the fuel injection on used one sprayer for all the cylinders, and it sprayed continually. The computer told it how heavily to spray; but it did not turn off between intake strokes.

I am not familiar with any system that operates the way you describe. I certainly haven't seen it all, but I have seen a lot in my 33 years of working on cars and trucks for a living.

The closest thing to what Garth described was probably the early GM throttle body injection system, which was more like carburetion than fuel injection. However, that system was timed, not constant flow. The fuel injection on my race car is constant flow, but injects through individual nozzles located in each intake runner above the throttle plates, which sacrifices low speed behavior for best top end performance. In some respects, it resembles modern port injection systems, but is purely mechanical in operation and is tailored for use with straight methanol or a methanol/nitromethane blend.
Attachment:
File comment: Kinsler Fuel Injection
racecar08.gif
racecar08.gif [ 1.2 MiB | Viewed 53557 times ]

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 7:59 pm 
Offline

Joined: Tue Jul 24, 2012 2:27 am
Posts: 672
Another use of BRK that I've seen in regards to VMs is to toggle from native 6502 code into bytecode. The handler would pop the caller's PC, put it into the software instruction pointer, and run the VM. Similarly, there's usually a corresponding bytecode which drops back from VM into 6502 mode for the next bytes.

However, if your processor is custom then having a specific instruction to switch from native mode to VM mode (however that may be handled) might be more applicable instead of a generic BRK.

_________________
WFDis Interactive 6502 Disassembler
AcheronVM: A Reconfigurable 16-bit Virtual CPU for the 6502 Microprocessor


Top
 Profile  
Reply with quote  
 Post subject: Re: 65VM02
PostPosted: Mon Jun 05, 2017 9:09 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
Hugh Aguilar wrote:
I used BRK in my debugger, and it really bloated out the code a lot. If I had used JSR BREAK instead, the bloat would have been considerably worse.

In what way? BRK is a 2-byte instruction (even if your BRK ISR ignores the 2nd byte. The RTI comes back to the 2nd byte after the 00 op code though, not the very next byte. So BRK takes 2 bytes, and JSR takes 3. The ISR and BREAK routines will be almost identical. JSR and BRK both leave the caller's return address on the stack, so some of the arguments in favor of BRK seem invalid. A subroutine can also get the status even though JSR didn't push it.

The debugger idea was one of the things I had in mind when I made my '816 Forth assembly source code optionally (by conditional assembly) assemble JMP (NEXTadr). It lets you have multiple versions of NEXT and switch between them on the fly, during execution, one being for tracing. As I got more experience with Forth though, I found I never needed the tracing.

Quote:
GARTHWILSON wrote:
In Forth, (ZP,X) is used to point to memory locations whose addresses are on the data stack, since the programmer won't know ahead of time where the top of the stack will be when the particular code is run. Storing, retrieving, or RMW instructions to locations whose addresses are on the data stack are all game. X is the stack pointer.

In my current design, I am assuming that a split-stack is used. This means that you have one stack for low bytes and one stack for high bytes, both indexed by X (I got this idea from ISYS Forth on the Apple-IIc that my cross-compiler was compatible with). The advantage here is that only one INX is needed to drop a 16-bit value from the data-stack, and one DEX to make room for a new 16-bit value.

Then you have the extra overhead of copying bytes from the two sides of the split to another location for indirects, like to fetch, to AND a cell with the contents of the memory location whose address is at the TOS, etc.. (Oh, I see you addressed this further down already.) However, I do like Jeff's idea of doing the high cell of doubles on a separate shadow stack using the same index. It looks like it would make stack manipulation when there are double-precision numbers involved more efficient. On the '02, doubles won't be used for addresses, only data, so there's no need to have all the bytes together for indirects. The drawback is that it breaks some code.

Quote:
I'm thinking now however, that I might change this and go with a combined stack in which the low and high byte are juxtaposed. This would involve adding these instructions:
Code:
DINX                add 2 to X          effectively the same as: INX INX
DDEX                subtract 2 from X   effectively the same as: DEX DEX

I've always though those would be nice to have. There's only one addressing mode needed for each, so it doesn't take much space in the op code table.

Quote:
A better idea is to introduce a new register called F that holds the local-frame pointer, rather than use the LF direct-page pointer. This involves adding a raft of new instructions though, which complicates the processor a lot. Whether this is worthwhile or not, depends upon how much local variables are used. In Forth, a lot of functions don't have local variables at all, but only use the data-stack. In C, Pascal, etc., the functions only use local variables and don't have a data-stack, so the F register would be hugely helpful to speeding up these languages.

That sounds like something else I've thought would be good to have. Be sure to look into the 816's stack-relative addressing modes too though. You might not copy it exactly, but it does open up a lot of capability.

Quote:
So, for an 8 cylinder engine at 6000 rpm, we have 2,500 microseconds, or 2.5 milliseconds.

If there should be 1/256 of a rev resolution (ie, 1.406° which should be plenty fine considering it takes a lot longer than that for a valve to open or close or for the flame wall to travel and fill the cyclinder, which I've seen in an engine with a glass head—it's definitely not instant), 1/256 of a revolution at 6000 rpm takes 39µs, which is still not very challenging for an '02. It would be easy to crank the interrupt latency number of cycles into the timing-advance calculations which have to be there anyway.

Quote:
I still don't know why a PowerPC/eTPU is needed --- that is a hugely powerful computer (significantly more powerful than the desktop computers of the early 1990s) --- maybe car manufacturers are just a conservative lot who feel more comfortable with a big powerful computer so there is no danger whatsoever of lacking enough computer power to do everything that anybody may ever think of needing.

Perhaps they were scared of the future expansion things they hadn't though of yet, and wanted to make sure there's more than enough power to cover the possibilities, kind of like how we used to keep upping our estimates of how much stack space we need until we actually measured and found out we weren't using nearly as much as we thought.

barrym95838 wrote:
I am not familiar with any system that operates the way you describe. I certainly haven't seen it all, but I have seen a lot in my 33 years of working on cars and trucks for a living.

After I wrote my last post above, I remembered you and hoped you'd pipe up, since you're probably the most knowledgeable one here about the subject. There's also ElEctric_EyE who originally jumped in here with his first post about some kind of ignition or engine controller IIRC, but it might have been more of a hobby for him rather than his living. (EE, I apologize if I'm not remembering correctly.)

My bro-in-law had a VW that worked that way, and someone gave our older son a Chrysler that worked that way. He let it sit for a long time and the gas in the only fuel sprayer went bad and clogged it, and he cleaned it out with graffiti remover. Worked fine.

I would think that spraying the fuel right into the cylinder during the intake stroke would result in worse emissions, not better, because the droplets would not have time to fully evaporate and for the vapor to thoroughly and evenly mix with the surrounding air. There's a lot in that whole field which I would be interested to know, but there aren't enough hours in the day to learn everything I'm interested in. I'm not sure I like some of the ideas in the Wikipedia article though. I don't want to own something so complex as some of those. I've heard that some systems' emission controls won't work right if the oil viscosity isn't correct. So how much do I pollute with my '88 vehicle? I drive only about 600-800 miles per year (not month). Most days it doesn't even get started up.

I've been interested in electric cars for decades; but a friend came over in his new hybrid and was showing me under the hood recently, and I didn't recognize anything, and there wasn't room to access anything either. Gone are the days you could step inside your pickup's engine compartment and quickly change out the alternator with a few simple tools, or quickly swap out a headlight for $10 (or even $2 if you didn't need the halogen type!). Years ago someone approached me to design a brushless DC motor controller for an electric car, and I looked over the requirements and found that a 65c02 could do the job with no problem.

Quote:
Now we just need to convince everyone that Forth is generally useful,

I do think it's useful for every programming application; but I have become more or less convinced that everyone's brains don't work that way. Mine does though. (I've seen an awful lot of bad Forth code though that I won't defend).

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 217 posts ]  Go to page Previous  1 ... 10, 11, 12, 13, 14, 15  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 12 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: