Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Stefan last won the day on October 3 2021

Stefan had the most liked content!

1 Follower

About Stefan

  • Birthday 01/03/1973

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Stefan's Achievements


Explorer (4/14)

Dedicated Rare Very Popular Rare First Post Rare Collaborator Rare Reacting Well Rare

Recent Badges



  1. My guess is that the community is not interested in the keyboard solution per se. We just want it to become functional so that we can get on with what really interests us, eventually owning and using a X16. I agree that the team should choose a proven design that is easy to implement. @Wavicle, do you see any problem supporting both keyboard and mouse with the ATTINY + I2C solution?
  2. As an I2C slave, the ATTINY cannot make too many assumptions on the data valid period on the I2C bus. I guess that is why I in my head ruled out that the ATTINY could serve both the PS/2 and I2C lines simultaneously. But you have tested this in hardware, and I see that it might work as you describe. I did some manual clock cycle counting on the Kernal I2C send_bit function to calculate for how long the clock line is held high. The clock transition from low to high happens at i2c.s line 223 The clock transition from high to low happens at line 210 Between those lines there are about 24 clock cycles = 3 us @ 8 MHz I don't know, but is it correct to say that the handlers for both the I2C and the PS/2 must run within that time to guarantee that you don't loose data? EDIT: By the way, I see that the ATTINY861 has hardware support for I2C (USI). Did you use this in your test or was the I2C bit banged? I was assuming the latter, but maybe that wasn't right. I would need to read more about USI.
  3. That is really interesting info, @SolidState. As to using I2C as transport layer between the ATTINY and the 65C02. I tried to measure the time it takes to run the Kernal function i2c_read_byte. Using the clock counter at $9fb8-9fbb I came to about 1,200 clock cycles. Manual counting of the Kernal code gave a similar result, but I didn't count every code path. 1,200 clock cycles are 150 us @ 8 MHz. It's clear that the ATTINY cannot be listening for incoming PS/2 data at the same time it makes an I2C transfer taking that time. The data valid period in the PS/2 protocol is much less than 150 us in my understanding. This means that if you are trying to use I2C to transfer scan codes to the processor, you must inhibit the PS/2 line while doing so. It feels wrong to do this, but it might work anyway. Even if the time it takes for the keyboard to come alive again after being disabled is 5,000 us, there is room for about 200 scan codes per second.
  4. I made two different changes to that code that were compiled and published in this thread on August 25. You need a real board to test it. I don't know if that was ever done by Kevin. The real problem is, as @Wavicle pointed out, that the PS/2 protocol wasn't designed to be used like this. There seems to be no standard on when a PS/2 device must become active after being disabled. The standard just says that it may not happen before 50 microseconds after the host has released the clock. It could be 50 microseconds, 100 microseconds, or any other duration. The standard doesn't prevent that it could differ from time to time even if you're using the same device (not very likely though). And different keyboards could have different delays, and so on.
  5. I still think using I2C will make matters more complicated, as evidenced by the fact that we have not yet a functional keyboard. The Veronica's keyboard, that I mentioned above, does not need to disable the PS/2 line during operation. After receiving the 11th bit of a PS/2 envelope, the keyboard controller directly puts the byte received onto the shift register which is then available to the 6522. There is enough time to do this before receiving the next PS/2 start bit. The 6502 may then read the byte from the 6522 with a simple LDA instruction. In other words, the 6502 and 6522 are used as designed. We shouldn't fight that. I don't know, but it feels like the PS/2 wasn't designed to be disabled after every scan code. There is, for instance, no standard saying how quickly the PS/2 device should start when enabled again, it's only said that it cannot start before 50 µs has passed.
  6. Nice work @Wavicle! What strategy did you have to handle PS/2-I2C conflicts? I mean what if PS/2 communication started while you were sending data over I2C. Did you just disable the PS/2 line while sending over I2C? How did you handle multibyte scan codes? Was there a buffer? One benefit of a shift register solution is that it might be possible to shift out bits even when receiving PS/2 data during the PS/2 clock inactive state. The inactive state is 30-50 us per bit corresponding to 300-500 processor cycles on the ATTINY @ 10MHz. Is that enough to transfer one byte? I think there's a good change you could make it fit if you look at the instruction set table for the ATTINY.
  7. I agree that we should refrain from both tea leaf reading, and Kremlinology, and focus on the request for assistance put out in Kevin's original post in this thread. As he hasn't yet thanked anyone for solving this, it's reasonable to believe that it isn't solved. My intuition is that using the I2C protocol to send keyboard and mouse data from the ATTINY over the 65C22 to the 65C02 is asking for unnecessary problems. Looking for solutions online, I particularly like at least some aspects of this one: https://blondihacks.com/veronica-keyboard/ The Veronica keyboard controller is a microprocessor that reads PS/2 data and pushes it to a shift register that is read by a 6522 which in it's turn is read by the 6502. The Veronica keyboard uses an interrupt to signal to the 6502 that there is PS/2 data to be read, and there is an interrupt handler that basically just stores the data to a keyboard buffer. The interrupt handler must run immediately and be as small as possible in order not to loose data, especially multibyte scan codes. As far as I understand, the 65C22 has a built-in shift register that could be used by the X16 instead of an external shift register. And there is also an unused 65C22 (VIA #2) on the board if that functionality cannot be put into VIA #1. I also think that a polling solution would be better than an interrupt firing at any time. This should be possible if the ATTINY buffers data until it's read.
  8. I see that Kevin said so in his original post. And that the PS/2 should be interrupt driven. My understanding of the 65C22 is very limited, but there is no mention in the datasheet of I2C support. As far as I can tell from the Kernal source, I2C is done by bit banging VIA pins. But yes, I suppose you could read and write data from/to the ATTINY using this kind of I2C communication. One thing that springs to mind is that the ATTINY then might need to drive three timing dependant serial interfaces simultaneously (two PS/2 and one I2C). Can it do all that? And if an NMI may be generated at any time to read PS/2 data as soon as it's available, will that cause problems for other timing dependant code running on the 65C02, for instance music? I feel it would be necessary to draw up some diagrams to fully understand how this is going to work low level.
  9. Continuing upon my last post here. Currently the PS/2 data and clock lines of the keyboard (and mouse?) are connected directly to VIA#1 PA0-1 and PB0-1, while VIA#2 is unused as far as I can tell. Thoughts on pin usage: The ATTINY 861 has 14 GPIO pins, and 3 of them are used for power control. That leaves us with 11 pins to handle keyboard and mouse Of these, 4 pins are needed to connect the keyboard and mouse PS/2 lines. Now we have 7 pins left That is clearly not pins enough to transfer one byte at a time from the ATTINY to the 65C22. Maybe you could manage to transfer one nibble at a time. But even nibble transfer requires control lines, like chip enable, data transfer direction (read/write), read/write handshake, and keyboard/mouse select. If byte or nibble transfers are not possible, we are stuck with serial transfer. It's very similar to connecting the keyboard directly to the VIA, however, with the benefit of having precise control over how the ATTINY sends the data it has buffered. Returning to @Kevin Williams's initial question in this thread: In order to write keyboard and mouse controller software for the ATTINY, there first needs to be a hardware design.
  10. Hi, On Facebook there was a post answered by David that I read today, and that said that there is yet no solution to the PS/2 issue. Unfortunately, I have no clear idea of how the 65C02 -> 65C22 -> ATTINY861 setup would work. Some thoughts: I suppose one possibility is that the ATTINY generates a NMI on the 65C02 when there is PS/2 data to be read. A drawback of this design is that the NMI could occur at any time, possibly disturbing other time critical code running on the 65C02. Another design option might be to let the ATTINY buffer PS/2 codes received, and to disable PS/2 communication if the buffer is full. To support both keyboard and mouse, there could be one buffer for each I suppose the ATTINY cannot handle both the keyboard and mouse simultaneously. Maybe there needs to be a priority, for instance so that on receiving PS/2 data from the keyboard the mouse PS/2 line is always disabled. With this setup the Kernal code could try fetching one PS/2 scan code from the keyboard and mouse buffers on each VBLANK.
  11. I guess you could use ADC, but it would be more code and slower. Assuming you are using r0 as zero page vector, this might work (not tested): ldx #<$8000 ldy #>$8000 stx r0 sty r0+1 loop: clc lda r0 adc #1 sta r0 lda r0+1 adc #0 ;Adding carry sta r0+1 lda (r0) ;Indirect addressing mode without Y, not supported by original 6502 beq end jsr $ffd2 ;Print char bra loop end: rts
  12. Yes. I'm not sure what you exactly mean. However, the INC, INX, INY, and INA opcodes don't affect the carry bit, so I guess the answer is no. In @Greg King's post above, there is a complete code sample using the Y register to walk through the low byte of the address. As may be seen in the sample, wrap around of Y is tested by checking for 0, not carry (the row BNE LOOP in Greg's code).
  13. Season's Greetings to all of you! We have a really nice community around the X16. And I couldn't agree more with @Johan Kårlin
  14. Version 0.1.0 published. New in this version is that BASLOAD is loaded as a normal BASIC program, that is with LOAD"BASLOAD",8, no need for ,8,1. You need to RUN the program to setup the environment. This copies BASLOAD to its final destination in RAM ($9000). It will also setup two "wedge" commands to make it a bit more convenient to program. Those wedge commands are !L to load a BASIC file and !E to start X16 Edit. New in this version is also that the program when starting X16 Edit first will look in the ROM banks for the editor. If not found there, it will try to load X16 Edit from the root folder of the SD card (as before).
  15. Great work @desertfish!!! Is included code within the same scope as code in the main file? I mean, must all labels and identifiers be unique in both the main file and all included files?
  • Create New...

Important Information

Please review our Terms of Use