Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Stefan

  1. X16 Edit supports that kind of function with the ESC key. You may press and release ESC and then any of the command keys.
  2. Hi @evlthecat. You cannot change the behavior of Ctrl+R in the Windows and Linux emulators from within a program that runs in the emulator. You would need to change the emulator itself. I hope that the real hardware will not have this problem. Finding other suitable shortcuts not interfering with any existing Ctrl+key sequence in Windows or Linux is a bit hard. I'm already using most available Ctrl+key combinations! And we would move away farther from GNU Nano. I don't know if it's a good solution, but it would be possible to support several modifier keys in parallel. That would make it possible to use, for instance, the Win key as an alternative to Ctrl. Which of the other modifier keys (Alt/Win/AltGr) would have least interference with Windows/Linux and the Kernal? I'm not sure. That requires some research.
  3. Thanks. Ctrl+V works in the emulator for me. I'm using MacOS. I know that the emulator behaves a bit differently on Windows and Linux. We would need to know if it works on the real hardware before changing it. END is supported for now by Shift+Home. This is because the Kernal ignores the END key. It seems R39 will include support for custom PS/2 scan code handlers, that let you catch a scan code before it's processed by the Kernal. This could be used to enable support for the real END, PageUp and PageDown keys even though the Kernal ignores those keys.
  4. I've been trying to adjust X16 Edit for the upcoming R39 Emulator+Kernal. As far as I can see, there are no issues whatsoever. I attach my R39-test (sources on Github in branch "prepare-for-R39"). https://github.com/stefan-b-jakobsson/x16-edit/tree/prepare-for-R39 Running it requires you to download and compile both the emulator and the Kernal from Github. If you haven't noticed, @Michael Steil merged most pending pull request for the Kernal during the end of last week and the weekend. I guess he is actively working towards R39. Happy times! X16EDIT-R39-TEST.PRG
  5. OK. Haven't tested it much, but there are no obvious artifacts.
  6. I tried to run my program X16 Edit on the emulator+Kernal at their current state on Github. It was easy to get it working. In my case, only changing the address in the definition of RAM and ROM bank select.
  7. This page has great info on the low level workings of the PS/2 interface: https://www.avrfreaks.net/sites/default/files/PS2 Keyboard.pdf There are only a few generally supported host to device commands. Most of them are not very useful. The two most interesting commands might be: 0xF3 <byte value>: Set key repeat rate and delay 0xED <byte value>: Turn on/off Num Lock, Caps Lock and Scroll Lock LEDs
  8. Hi @SlithyMatt The keyboard interface was discussed recently in these threads: https://www.commanderx16.com/forum/index.php?/topic/909-how-does-ps2-keyboard-interface-work/ https://www.commanderx16.com/forum/index.php?/topic/1156-are-ps2-host-to-device-commands-supported-in-the-emulator/ After reading the Kernal source for some time, I have come to the following conclusions: The Kernal doesn't control key repeat in any way PS/2 keyboards have key repeat built in In order to control the repeat rate, you need to send a command from the host (=X16) to the keyboard There is no support in the Kernal for sending commands to the keyboard, but you could implement it yourself. To test this you would need the real hardware, as the emulator doesn't seem to react to such commands. The counter initialized to 10 you refer to might by the one at kernal/drivers/x16/ps2.s line 56. If this is the point in the code you mean, it is actually initialized to 10 * 8 = 80. As far as I understand, the Kernal in this loop repeatedly polls the PS/2 lines looking for a start condition set by the keyboard. If no start condition is found before the end of the loop, the Kernal disables the PS/2 communication until next VBLANK interrupt. And the Kernal reads only one scan code during each VBLANK. One scan code may consist of several bytes though. I tried to manually calculate the time the Kernal spends in that loop waiting for a start condition, and came to 110 us. I've read that a PS/2 device should not start communication until 50 us after the clock line is released by the host, so 110 us seems to be a reasonable number.
  9. A small correction to my previous post The ps2_receive_byte doesn't poll the PS/2 state 10 times, but 10 times multiplied by processor frequency in MHz => 80 times in total Manually calculating the cycles spent in the polling loop, I got 11 cycles per loop (more if the code would be split over a page boundary) That sums up to 880 cycles equivalent to about 110 us @ 8 MHz I've read that a PS/2 device is required to buffer data to be sent if the host holds the clock line low, and that transmission should begin not before 50 us after the clock line is released The Kernal is waiting and polling the PS/2 state for about 0.66% of the total VBLANK (0.01667 s @ 60 Hz), if my calculations are right (= 0.00011 s / 0.01667 s). And probably double that time if we take into consideration the PS/2 mouse
  10. I think the Kernal (R38) currently does the following. At system startup: ioinit function is called (kernal/cbm/init.s:20) ioinit function calls ps2_init function (kernal/drivers/x16/x16.s:27) ps2_init disables all PS/2 communication by pulling clock pin low and data pin high (kernal/drivers/x16/ps2.s:27-38) As far as I understand, the PS/2 communication stays in this state until VBLANK: The function kbd_scan is called as part of the IRQ handler (kernal/cbm/irq.s:50) kbd_scan calls _kbd_scan (kernal/drivers/x16/ps2kbd.s:49) _kbd_scan calls receive_down_scancode_no_modifiers (kernal/drivers/x16/ps2kbd.s:126) receive_down_scancode_no_modifiers calls receive_scancode (kernal/drivers/x16/ps2kbd.s:261) receive_scancode calls ps2_receive_byte (kernal/drivers/x16/ps2kbd.s:225) ps2_receive_byte is the function that actually fetches PS/2 data: First it releases the clock and data pins (kernal/drivers/x16/ps2.s:51-53). As you might remember, these pins were pulled low and high at system startup. The function polls the state of the clock and data pins at most 10 times (kernal/drivers/x16/ps2.s:55-60) looking for a start condition (clock and data low). I guess 10 times is a timing issue. I haven't done the math on how much time is really spent in that loop before aborting. If no start condition found within the 10 loops: Branch to line 98 where the ps/2 disable function is called, the same that disabled PS/2 communication at system startup If start condition found: 8 bits and 1 parity bit are read and stored (kernal/drivers/x16/ps2.s:62-81) ps2dis is called to disable PS/2 communication again (kernal/drivers/x16/ps2.s:82). And finally the function returns after loading the received byte into A Some conclusions: The Kernal isn't faking it. It reads a byte bit by bit, as you would expect PS/2 communication is disabled almost all the time by the Kernal pulling the clock and data pins The Kernal only releases the clock and data pins every VBLANK to read the keyboard It reads the keyboard by polling the state for a period of time that is sufficiently long to follow PS/2 standard The above suggests that there is no special IRQ line driven by the keyboard. I'm sorry if I have misunderstood any aspect of how this works. It will be interesting to see what changes, as the team is redesigning this code according to @Lorin Millsap above in this thread.
  11. AFAIK it's not the emulator that preprocesses control keys. The PS/2 scan codes are processed by the Kernal. To change the behavior you need to change the Kernal. The Kernal's translation from PS/2 scan code to ASCII/PETSCII is quite a complicated affair. There are tables for each supported keyboard layout in the ROM image (source code path: x16-rom/keymap).
  12. Yes, it's safe to assume that you cannot just pipe the PS/2 data stream from the emulator to the host OS. But the emulator could listen for PS/2 commands and respond in meaningful ways, for instance turning on LEDs on the keyboard used by the host OS. Implementing this kind of functionality might not be trivial, though. Therefore I'm satisfied waiting for the hardware.
  13. Hello! I'm trying to make a function to send a byte to a PS/2 device (the keyboard). This could be used to set different keyboard properties, such as the key repeat rate. As far as I have seen, the Kernal only has the opposite function, to receive a byte from a PS/2 device. It should be possible to implement such a function yourself. But there are quite a few low level steps in order to send a byte to a device. Several steps depend on timing constraints. It's easy to mess something up... My test function doesn't hang, but it does neither produce any visible result with the commands I have tried (see included file for code). Does anybody know if the emulator at all supports sending commands from the host to a device in this manner? ps2.inc
  14. Ambitious project @paulscottrobson! Do you intend to store programs as plain text or as tokenized files? If plain text, I guess you could use the text editor I've been working on to write BASIC code. Please let me know if you require anything special to make that work. EDIT: And I almost forgot. If you feel old school, there is also the LED in the downloads section. I like that a lot. It's surprisingly efficient to use.
  15. Maybe it's worth looking at CRC-16 and CRC-32. Probably not ideal, but seems to be easily calculated. Is it good enough for your purpose? One implementation is found here (without lookup tables): http://www.6502.org/source/integers/crc-more.html And another here (with tables): http://www.6502.org/source/integers/crc.htm
  16. Sure is. Any idea about a suitable hash function?
  17. Unless you plan to allow redefined symbols, the assembler could throw an error when it encounters a duplicate definition, whether an actual duplicate or a false match.
  18. According to the book Starting Forth, the Forth-79 standard allowed symbol names of up to 31 characters. But some variants of Forth only stored three characters + the length of the symbol. "name1" and "name2" would then be the same, which is not ideal. I don't suggest that you copy that approach as is. It's more an inspiration. There's always the risk for collisions. Checksums/hashes are probably better than symbol length. Only storing the first three characters is probably too little.
  20. Nice progress @desertfish! I mostly works as expected when I made my own simple "hello world". I also put the string at the end of the code as in your own hello world test. I tried to load each character in the loop with lda message,x and lda message,y, but that failed. Apparently the assembler did not recognize a label defined later in the code. It worked fine when I changed "message" to a fixed hexadecimal address. If symbols with 32 characters would become too heavy, you could always do what's been done in other languages, for instance Forth. Store only the first few characters of a symbol in the symbol table Also store some other metadata in the symbol table, for example the length and/or a checksum, thereby minimizing false duplicates This could save space and speed up assembly
  21. Hello. I'm by no means an expert on PS/2 scan codes. According to tables available on line, for instance here https://techdocs.altium.com/display/FPGA/PS2+Keyboard+Scan+Codes, it seems that the only key with prefix $E1 is the Pause/Break key. The Esc key make code is $76. Looking at the Kernal source at kernal/drivers/x16/ps2kbd.s Keyboard scan routine starts at line 125 At line 132 it branches to line 177 (label: down_ext) if the PS/2 prefix is not 0 If the PS/2 prefix is $E1 we got the Pause/Break key I have no working Pause key on my Mac, so I cannot test what happens. However, it seems that the X register is loaded with value #6 on line 205, which is moved to A register on line 208 and divided by 2 on line 209 before sent to the keyboard buffer. 6 divided by 2 is the code for the Esc key. So I would guess that Esc and Pause/Break is ending up doing the same. The Esc key breaks Basic code. In assembly programs, I would say that the Esc key doesn't have any function, other than what you tell it to.
  22. I totally agree. We have a lot of memory and disk to play with.
  23. True. But CLOSE first commands the device to be a listener, thereby stopping it to talk, if it was a talker. Issuing the UNTALK command should have no effect on the device after CLOSE, in my understanding. I agree that it's safe to continue using CLRCHN. UNTALK and UNLISTEN ensure that all devices are in a passive (non-talking and non-listening) state.
  24. I've been reading more about CLOSE and CLRCHN in the Kernal sources and in @Michael Steil 's article published here: https://www.pagetable.com/?p=1031 CLOSE sends the following commands on the serial bus: LISTEN <device number> CLOSE <file number> UNLISTEN CLRCHN does the following: Sends UNTALK <input device> Sends UNLISTEN <output device> Sets defltn (address $028A) and deflto (address $028B) to their default values, i.e. output=3 (screen), and input=0 (keyboard) I would think that after calling CLOSE it will not matter to the device on the serial bus if also you call CLRCHN. As CLOSE has already sent LISTEN-CLOSE-UNLISTEN, the device will neither talk nor listen whether or not you call CLRCHN. So if you have called CLOSE on all files, calling CLRCHN is only meaningful in order to reset the input and output device numbers used by the Kernal (defltn and deflto). As @svenvandevelde was writing above, it makes perfect sense to call CLRCHN after you are completely done with the I/O operation, as you could be dealing with more than one file at the same time. But the above also, I would say, show that it doesn't really matter in what order you are calling CLOSE and CLRCHN.
  • Create New...

Important Information

Please review our Terms of Use