6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Sep 21, 2024 9:25 pm

All times are UTC




Post new topic Reply to topic  [ 354 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 24  Next
Author Message
PostPosted: Wed May 15, 2019 11:59 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
JimBoyd wrote:
Here is a table of which device is accessed depending on block number:
Code:
Block access
+---------------+----------+--------+----------------+----------------------+
|  Range of     | Device   | Access | Block range    | Notes                |
|  blocks       |          | word   | seen by device |                      |
+---------------+------------+----- --+----------------+--------------------+
| $0000 - $0FFF | drive 8  | DR/W   | 0000 - $0FFF   | Actual disk drive    |
| $1000 - $1FFF | drive 9  | DR/W   | 0000 - $0FFF   | block ranges limited |
| $2000 - $2FFF | drive 10 | DR/W   | 0000 - $0FFF   | by drive capacity    |
| $3000 - $3FFF | drive 11 | DR/W   | 0000 - $0FFF   |                      |
| $4000 - $4FFF | drive 12 | DR/W   | 0000 - $0FFF   |______________________|
| $5000 - $FFFF |   REU    | RR/W   | 0000 - $AFFF   | REU max capacity     |
|               |          |        |                | is 4000 blocks       |
+---------------+----------+--------+----------------+----------------------+


A reminder, just because a device "sees" a given block range doesn't mean it has the capacity for said range. The single sided and single disk 1541 can only handle block numbers 0 - 165 ( 0 - $A5 ).
VICE, the C64 simulator allows simulating a Ram Expansion Unit with a maximum size of 16 megabytes ( 256 banks ) for a block range of 0 - 16383 ( 0 - $3FFF ). The actual Ram Expansion Unit I had back then had a capacity of 512k ( it was the one for the C128 but worked fine with the C64 ). It had a block range of 0 - 511 ( 0 - $1FF ). In actual use, I've only used a couple dozen or so blocks in the Ram Expansion Unit.


Top
 Profile  
Reply with quote  
PostPosted: Fri May 24, 2019 11:54 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
The Fleet Forth metacompiler has a new feature.
In another thread, Garth Wilson commented:
GARTHWILSON wrote:
The 6502 Forth I got started on used lower-case for the internals, and I have stuck with that. So for example, DO compiles do, LOOP compiles loop, IF compiles 0branch, etc.. It's shorter than (do), (loop), etc.. which I think fig-Forth does, and if you want to put it in a comment marked out by parentheses, you can, without ending the comment prematurely.

Since the DO LOOP primitives are only used by the DO LOOP compiling words, I was wondering if anyone thought about naming the primitives the same thing. DO would compile a primitive named DO , LOOP would compile a primitive named LOOP , etc. .
The Fleet Forth metacompiler does not allow redefinitions within the target vocabulary and for good reason. The metacompiler builds the target in virtual memory. For each word that is defined, a 'target word' is added to the target vocabulary on the host. the target words are CREATE DOES> words with three cells in their parameter fields. The first cell is the virtual address of the corresponding word in the target, the address it will have in the new kernel. The second address is the address of the word that was found with the same name ( usually found in the META vocabulary or the host FORTH vocabulary). The third cell is for statistical data ( how many times was this word compiled into a new definition? ). While interpreting, or if the target word is immediate, the target word ( the word in the target vocabulary on the host ) is executed. All target words have the same behavior, fetch the address in their second cell, abort with a message if it is zero, otherwise execute it. There are metacompiler versions of the compiler words in the META vocabulary. When compiling a word in the target that has a DO LOOP , the META versions of these words are found and executed. If the target versions of these words are already defined, the target word executes the META version when it is executed.
The problem arises if the primitive and compiling word for DO have the same name. If the compiling word has not been defined yet and a DO LOOP is used in the source of a word ( the primitives having already been defined ) , the primitive in the target will be found and compiled! No in line branching addresses will be compiled, just the primitive.
The metacompiler's new feature adds a name buffer which normally has a zero in the first byte. If there is a non zero value in the first byte, the name in the buffer is used for the name in virtual memory. If I want to name the DO primitive DO , I can do it like this:
Code:
// (DO)
HEX
T" DO"
CODE (DO)  ( N1 N2 -- )
   < CODE FOR (DO) >
END-CODE

The target word for the DO primitive will have the name (DO) , but the actual name for the primitive in the new kernel will be DO .
If I want to leave the name in the new kernel the same as in the source ( (DO) ) , I just leave out the T" <name>" .
Code:
// (DO)
HEX
CODE (DO)  ( N1 N2 -- )
   < CODE FOR (DO) >
END-CODE


Top
 Profile  
Reply with quote  
PostPosted: Sun May 26, 2019 1:47 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
T" has been replaced with VN ( virtual name ) which accepts a blank as a delimiter instead of a quote mark.
This:
Code:
// (DO)
HEX
T" DO"
CODE (DO)  ( N1 N2 -- )
   < CODE FOR (DO) >
END-CODE

now becomes this:
Code:
// (DO)
HEX
VN DO
CODE (DO)  ( N1 N2 -- )
   < CODE FOR (DO) >
END-CODE

This change was made so I could also do this:
Code:
VN ABORT"
: (ABORT")  ( FLAG -- )
   .
   .
   .

VN ."
: (.")
   .
   .
   .

When a primitive has the same name as its compiling word, the disassembly looks a little odd.
Code:
SEE (DUMP)
(DUMP)
 16970 14018 BOUNDS
 16972  2227 DO 16990
 16976  4115 I
 16978  4933 C@
 16980 15741 8BITS
 16982  7695 .R
 16984  7381 SPACE
 16986  2308 LOOP 16976
 16990  2381 EXIT
22
 OK
SEE DO
DO IMMEDIATE
 11720  8179 COMPILE
 11722  2227    DO
 11724 11474 >MARK
 11726  4744 2+
 11728 11494 <MARK
 11730  4744 2+
 11732  2381 EXIT
14
 OK


Top
 Profile  
Reply with quote  
PostPosted: Thu May 30, 2019 8:29 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
BigEd wrote:
Hmm. Interesting problem - there will always be too many possible answers. Would it be too painful to say that these words return a full precision result, rather than half precision? That feels like the right answer, as the calling program presumably needs to be prepared to use the result, and the result might indeed be too large for half precision.

Well, with the unsigned integer square root ( no rounding), the result requires half as many bits as the initial number.
Quote:
Is there a means of signalling overflow?

The versions that do not round the result only return a zero result if taking the square root of zero. The rounding versions only return a zero result if taking the square root of zero or if there was an overflow. If your program never takes the square root of zero, then a zero result can only mean an overflow. I'm just going to go with returning a result as large as the input for the versions that round. The truncating versions don't need the extra size for the output.
Quote:
(I'm reminded of the difficulty in fixed-point that -1 is expressible, but +1 is not, so you can't square -1)

Huh? It's my understanding that a fixed point number is an integer where a suitable scale factor is used. For example, if I'm using a scale of 1000 then 2.718 is represented as 2718 and 3.142 is represented as 3142. Wouldn't +1 simply be represented as 1000?


Top
 Profile  
Reply with quote  
PostPosted: Thu May 30, 2019 8:37 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
JimBoyd wrote:
Quote:
(I'm reminded of the difficulty in fixed-point that -1 is expressible, but +1 is not, so you can't square -1)

Huh? It's my understanding that a fixed point number is an integer where a suitable scale factor is used. For example, if I'm using a scale of 1000 then 2.718 is represented as 2718 and 3.142 is represented as 3142. Wouldn't +1 simply be represented as 1000?

In twos-complement binary, there's always one more negative value than there are positive values. So, no matter how you scale things, the square of the most negative value is too large to fit as a positive value. I was thinking specifically of a setup where the numbers run from -1.0 to just shy of 1.0.


Top
 Profile  
Reply with quote  
PostPosted: Thu May 30, 2019 8:56 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
BigEd wrote:
JimBoyd wrote:
Quote:
(I'm reminded of the difficulty in fixed-point that -1 is expressible, but +1 is not, so you can't square -1)

Huh? It's my understanding that a fixed point number is an integer where a suitable scale factor is used. For example, if I'm using a scale of 1000 then 2.718 is represented as 2718 and 3.142 is represented as 3142. Wouldn't +1 simply be represented as 1000?

In twos-complement binary, there's always one more negative value than there are positive values.

True.
Quote:
So, no matter how you scale things, the square of the most negative value is too large to fit as a positive value.

As long as the absolute value is not less than one. For example: -0.5 to just shy of 0.5
Quote:
I was thinking specifically of a setup where the numbers run from -1.0 to just shy of 1.0.

Interesting. I never considered that case, till now, but then I am only a hobbyist, not a professional.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 09, 2019 2:18 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
Here is the set of Auxiliary stack words I've settled on:
Code:
SCR# 2A
// >A
HEX
CODE >A  ( S: N -- ) ( A: -- N )
   HERE 6 + JSR,  POP JMP,
   AP0 @ LDY,  DEY,  DEY,
   0< IF,
      >FORTH
      TRUE ABORT" AUX STACK FULL!"
      >ASSEM  -2 ALLOT
   THEN,
   0 ,X LDA,  APLIM @    ,Y STA,
   1 ,X LDA,  APLIM @ 1+ ,Y STA,
   AP0 @ STY,
   RTS,
END-CODE

SCR# 2B
// DUP>A 2>A CS>A
HEX
CODE DUP>A  ( S: N -- N ) ( A: -- N )
   ' >A @ 6 + JSR,
   NEXT JMP,  END-CODE
CODE 2>A  ( S: D -- ) ( A: -- D )
   INX,  INX,  ' >A @ 6 + JSR,
   DEX,  DEX,  ' >A @ 6 + JSR,
   POPTWO JMP,  END-CODE
CODE CS>A  ( S: CS -- ) ( A: -- CS )
   -2 ALLOT
   ' 2>A @ ,  END-CODE

SCR# 2C
// A>
HEX
CODE A>  ( S: -- N ) ( A: N -- )
   HERE 6 + JSR,  NEXT JMP,
   AP0 @ LDY,
   AP0 @ 1- 0FF AND # CPY,
   0< NOT IF,
      >FORTH
      TRUE ABORT" AUX STACK EMPTY!"
      >ASSEM  -2 ALLOT
   THEN,
   DEX,  DEX,
   APLIM @    ,Y LDA,  0 ,X STA,
   APLIM @ 1+ ,Y LDA,  1 ,X STA,
   INY,  INY,  AP0 @ STY,
   RTS,  END-CODE

SCR# 2D
// A@ 2A> A>CS
HEX
CODE A@  ( S: -- N ) ( A: N -- N )
   ' A> @ 6 + JSR,
   DEY,  DEY,  AP0 @ STY,
   NEXT JMP,  END-CODE
CODE 2A>  ( S: -- D ) ( A: D -- )
   ' A> @ 6 + JSR,
   ' A> @ 6 + JSR,
   ' SWAP @ JMP,  END-CODE
CODE A>CS  ( S: -- CS ) ( A: CS -- )
   -2 ALLOT
   ' 2A> @ ,  END-CODE

AP0 and APLIM are Fleet Forth user variables. AP0 is $256 and APLIM is $200. Location $256 also serves as storage for the Aux stack pointer. This address range is part of the BASIC input buffer on the Commodore 64. Fleet Forth uses the address range $2A7 - $2FF , an otherwise unused section, for its text input buffer.
In Fleet Forth, the control flow stack is the data stack and each control flow stack item ( CS ) is two cells, an address and a security number, so CS>A is an alias for 2>A and A>CS is an alias for 2A>.
The Aux stack words >A , DUP>A , 2>A , A> , A@ and 2A> are slower than their return stack counterparts, even though they are defined in code, but could be useful when testing a new word that needs to place temporary data to the return stack. Use these words to use the Aux stack instead of the return stack to test the new word or words since an Aux stack overflow or underflow will not, of itself, cause a system crash ( unlike the return stack). It is also easier to see what is happening if the only data on the extra stack is only what the word under test placed there ( or was placed there for it ). When the new word works successfully, the Aux stack words can be replaced with their return stack counterparts.
To see what is on the Aux stack, here is .AS
Code:
SCR# 35
// ADEPTH .AS
HEX
: ADEPTH  ( -- N )
   AP0 @ [ AP0 @ ] LITERAL @ - 2/ ;
: .AS  ( -- )
   SETWIDTH  ADEPTH DUP 0
   ?DO
      AP0 @ I 2* - 2- @
      16BITS DUP 2+ ?CR U.R SPACE
   LOOP
   ?EXIT
   ." EMPTY " ;

.S was rewritten so it never aborts:
Code:
HEX
: .S  ( -- )
   SETWIDTH
   DEPTH DUP 0 MAX 0
   ?DO
      DEPTH I - 1- PICK
      16BITS DUP 2+ ?CR U.R SPACE
   LOOP
   ?EXIT
   ." EMPTY " ;

and ABORT , which is called by the word compiled by ABORT" , is defined as:
Code:
: ABORT  ( -- )
   ERR SP! AP! QUIT ; -2 ALLOT

ERR is a deferred word that is normally set to execute NOOP , a no-op.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 13, 2019 8:00 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
I made a slight mistake with two of the Aux stack words. CS>A and A>CS should be immediate.
Code:
CODE CS>A  ( S: CS -- ) ( A: -- CS )
   -2 ALLOT
   ' 2>A @ ,
END-CODE  IMMEDIATE

CODE A>CS  ( S: -- CS ) ( A: CS -- )
   -2 ALLOT
   ' 2A> @ ,
END-CODE  IMMEDIATE


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 23, 2019 6:48 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
JimBoyd wrote:
Since the DO LOOP primitives are only used by the DO LOOP compiling words, I was wondering if anyone thought about naming the primitives the same thing. DO would compile a primitive named DO , LOOP would compile a primitive named LOOP , etc. .

I tried this partly to establish a baseline for my next experiment: making the DO LOOP primitives headless. This didn't pose any insurmountable problems with the design of the decompiler. The kernel was a few dozen bytes smaller ( I also made the primitives for ." and ABORT" headless ). The complete system with tools was almost three dozen bytes larger partly so the decompiler could display something for the headless primitives.
Overall, I wasn't very satisfied with either approach and went back to primitives with heads and with their original names ( (DO) (?DO) (LOOP) (+LOOP) (.") and (ABORT") .
GARTHWILSON wrote:
The 6502 Forth I got started on used lower-case for the internals, and I have stuck with that. So for example, DO compiles do, LOOP compiles loop, IF compiles 0branch, etc.. It's shorter than (do), (loop), etc.. which I think fig-Forth does, and if you want to put it in a comment marked out by parentheses, you can, without ending the comment prematurely.

Sadly, that's not really an option on the Commodore 64. The C64 lacks a caps lock key, it has a shift lock key instead. The C64's default character set looks like upper case when not shifted and graphical characters when shifted.
I've read that some Forth's gave the primitives names like <DO> <?DO> etc. to avoid problems with parentheses delimited comments. I suppose the names could be <DO <?DO etc. to make them slightly shorter. Any thoughts on this?


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 24, 2019 4:15 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8510
Location: Southern California
Since they're internals, I suppose you could call them whatever you want (just as you can make them headerless).

_________________
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  
PostPosted: Thu Jul 11, 2019 9:12 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
I had an idea for DEFERred words but I don't know if it is worth the overhead. In this post, vector refers to the word a DEFERred word is set to execute. In Fleet Forth, the DEFERred words defined in the kernel have a reset table. Forget goes through this table and resets any DEFERred word that had its vector forgotten. This only covers DEFERred words in the kernel. My idea was to add a new variable DEFER-LINK and add an extra cell to each DEFERred word as it is defined ( to link it into this DEFER-LINK chain). FORGET could traverse this link, after pruning the dictionary, and any DEFERred word that has its vector forgotten would be reset to -SET .All DEFERred words are initially set to this word. -SET displays the DEFERred word ( in reverse video) and the message "NOT SET" .
As I said, I'm not sure if this would be worth the overhead of an extra cell per DEFERred words plus the extra code in the kernel since the kernel DEFERred words are already covered.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 14, 2019 7:38 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
JimBoyd wrote:
I'm still working on getting multitasking and vectored I/O playing nice together.
... I'm thinking of trying something like this:
Code:
' NOOP VALUE CIO  // CURRENT I/O
<MORE CODE>


I've removed the multitasker support ( such as it was and what there was of it) from the vectored I/O words CONSOLE , PRINTER , and LOGGER. Fleet Forth still supports multitasking, but there are better ways than maintaining an I/O state variable to do what I wanted.
I have also reworked the I/O redirection so that an abort does not cause an I/O reset. This made it easier to log certain tests that would cause an abort ( intentionally as part of the test or even as the result of a typo) . By 'log', I mean send output to the console and the printer. Most of the I/O words that call a Commodore I/O routine return an error number on the data stack. IOERR takes this number and reports the error and aborts if the number is not zero. ?IO was added. It checks the error number and exits if the number is zero otherwise it calls IORESET and IOERR ( which aborts.) The only words which have ?IO are the new vectors for EMIT , TYPE , QTYPE , and EXPECT .
Here are the updated I/O redirection words:
Code:
SCR# 36
// OUTPUT REDIRECTION
HEX
// PRINTER DEVICE NUMBER
4 VALUE #LP
// PRINTER SECONDARY ADDRESS
0 VALUE #LP2
: ?IO  ( F -- )
   ?DUP 0EXIT IORESET IOERR ;
: (PEMIT)  ( C -- )
   #LP CHKOUT ?IO
   (EMIT) CLRCHN ;
: (PTYPE)  ( ADR U -- )
   #LP CHKOUT ?IO  (TYPE) ;

SCR# 37
// (PQTYPE)
HEX
: (PQTYPE)  ( ADR CNT -- )
   #LP CHKOUT ?IO
   >ASSEM
   2 # LDA,  SETUP JSR,
   BEGIN,
      BEGIN,
         N CPY,
         0= IF,
            N 1+ LDA,
            0= IF,
               ' CLRCHN @ JMP,
            THEN,
            N 1+ DEC,
         THEN,

SCR# 38
// (PQTYPE)
         N 2+ )Y LDA,
         BL # CMP, CS IF,
            7B # CMP, CS IF,
               0C1 # CMP, CS IF,
               0DB # CMP, CS ELIF,
         CS-ROT THEN,
            5F # LDA,
            THEN,
         THEN,
         ' (EMIT) @ 8 + JSR,  INY,
      0= UNTIL,
      N 3 + INC,
   AGAIN,
END-CODE

SCR# 39
// LOGGER REDIRECTION
HEX
: (LEMIT)  ( B -- )
   DUP DEMIT  (PEMIT) ;
: (LTYPE)  ( ADR CNT -- )
   2DUP DTYPE  (PTYPE) ;
: (LQTYPE)  ( ADR CNT -- )
   2DUP CHARS @ -ROT (PQTYPE)
   CHARS ! (QTYPE) ;
: (LEXPECT)  ( ADR CNT -- )
   OVER SWAP (EXPECT)
   #LP CHKOUT ?IO
   SPAN @ DTYPE BL DEMIT CLRCHN ;

SCR# 3A
// CONSOLE PRINTER LOGGER
HEX
: CONSOLE  ( -- )
   IORESET  #LP CLOSE ;
: PRINTER  ( -- )
   CONSOLE
   0 0  #LP DUP #LP2 OPEN IOERR
   ['] (PEMIT) IS EMIT
   ['] (PTYPE) (IS) TYPE
   ['] (PQTYPE) (IS) QTYPE ;
: LOGGER  ( -- )
   PRINTER
   ['] (LEMIT) IS EMIT
   ['] (LTYPE) (IS) TYPE
   ['] (LQTYPE) (IS) QTYPE
   ['] (LEXPECT) IS EXPECT ;

By the way, DEMIT and DTYPE are the versions of EMIT and TYPE normally used to send commands to a disk drive. They do exactly what EMIT and TYPE do except update the variables CHARS and LINES .


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 14, 2019 7:40 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
On the subject of DEFER. Is vector a good name for the word a DEFERred word is set to execute or is there a better one?


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 16, 2019 12:20 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
I was just rereading the thread on Extra stacks.
I named the words to transfer data between the data stack and the auxiliary stack with an 'A' rather than an 'H' because I didn't write the Auxiliary stack to be a high precision math stack, but rather a helping hand for manipulating high level and assembly control flow data. That and I wasn't thinking about that thread at the time I implemented the Aux stack.
As for implementing a split stack, that might save a few bytes in the stack transfer words, but it would cost more than that in the definition of .AS , the Aux stack counterpart to .S .


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 20, 2019 8:08 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
Fleet Forth has vectored (deferred) I/O words. Here is why.
Fleet Forth, like 64Forth and Blazin' Forth, uses the Commodore 64's I/O routines to save memory. On the Commodore 64, the same routine is used to send a byte to the screen, the printer, disk, or another device. There are Commodore 64 routines to redirect output to an open file, input from an open file, and to clear the I/O channels so output goes to the screen and input comes from the keyboard.

Fleet Forth's default I/O state is that the I/O channels are cleared and output goes to the screen while input comes from the keyboard. Both the cold start and warm start routines clear the I/O channels.

Words which perform disk I/O use one of the Commodore 64 KERNAL routines to redirect input or output to the specified open file. Data is read or written then the channel is cleared.

Redirecting output to a printer is handled similarly. There is a printer version of (TYPE) , the TYPE primitive. This printer-(type) , (PTYPE) , redirects output to the printer, types its data to the printer then clears the channel. PRINTER opens a channel to the printer and re-vectors TYPE, EMIT, and others to their printer versions. CONSOLE resets TYPE, EMIT, and others to their default vectors and closes the channel to the printer.

64Forth and Blazin' Forth do not re-vector EMIT and TYPE. They each have a word that opens a channel to the printer and redirects output to the printer. They also have a word that clears the channel and closes the file to the printer. 64Forth warns that when using PRINT to send a block listing to the printer, the block must already be in a buffer. Blazin' Forth does a little better. Blazin' Forth has a variable, PRINTING? , that gets set by PRINTER and cleared by NOPRINTER. Blazin' Forth's (LINE) , which is used by a word which is used by Blazin' Forth's LIST , has some extra code to check if PRINTING? is true and clear the I/O channel if it is. It also has some extra code after calling BLOCK to see if PRINTING? is true and redirect output to the printer if it is. The same goes for Blazin' Forth's word .INDEX ( which is used by INDEX ). This works for listing blocks to a printer or even sending the index of blocks to the printer, but it doesn't work when loading blocks and a block causes a message to be displayed. Since PRINTER? is defined in Blazin' Forth's system loader, it wasn't available when the block read write routine was written.

This is why Fleet Forth's EMIT, TYPE and some other words are deferred and the printer version of these words, like any word in Fleet Forth that communicates with devices other than the screen and keyboard, redirect the Commodore 64's I/O, send the data, and clear the I/O channel. In my opinion, it is much easier to start with a known state and return to that state ( I/O directed at keyboard and screen) than it is to try keeping up with the state of the I/O and trying to set it to what it was prior to the latest time it was redirected.

Note: The information in this post is specific to the Commodore 64 and interacting with the Commodore 64's KERNAL routines.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 354 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 24  Next

All times are UTC


Who is online

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