Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Stefan

  1. 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
  2. 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.
  3. 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
  4. 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.
  5. 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.
  7. 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
  8. 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.
  9. I totally agree. We have a lot of memory and disk to play with.
  10. 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.
  11. 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.
  12. Your tracker looks very nice by the way. Another thing. Apart from PageUp and PageDown, the user experience is also affected by the key repeat rate, i.e. the rate at which a key is repeated while held down. In a keyboard controlled program, the user-experience is often better if the repeat rate is fast. Fast repeat decreases the need for other cursor movement options, such as PageUp/PageDown/GotoNextWord and so on. I recently made a post regarding the key repeat rate. In the C64, this was apparently controlled by the Kernal. Skimming through the X16 Kernal, there seems to be no mechanism for key repeat control. I think the repeat rate will be controlled by the PS/2 keyboard controller. If you change the key repeat rate in your host system, this will also affect the key repeat rate in the emulator, suggesting that the Kernal is not handling this property. But then, how can you set the key repeat on a real X16? I have seen that you may send commands from a computer to a PS/2 keyboard to set, for instance, the key repeat rate. As for now there is no function in the Kernal to support that. It would, however, be doable to implement this yourself, if need be.
  13. Hi, PageUp and PageDown are simply not supported by the Kernal keyboard routine. As for now, you have no other feasible option than to use some other key or key sequence. There are also some issues with the GETIN routine inherited from the C64. One problem is that there are overlapping values (for instance ESC is the same value as Ctrl+C). And another is your problem that modifiers don't affect the arrow keys. In the Kernal, there is in fact a routine to read modifier key status. That routine is kbdbuf_get_modifiers (call address $ca64 in emulator R38). It returns a value in .A where bits 0 to 4 represents the modifiers as follows: KBD_MODIFIER_SHIFT = 1 ; C64: Shift KBD_MODIFIER_ALT = 2 ; C64: Commodore KBD_MODIFIER_CTRL = 4 ; C64: Ctrl KBD_MODIFIER_WIN = 8 ; C128: Alt KBD_MODIFIER_CAPS = 16; C128: Caps You could use kbdbuf_get_modifiers to catch sequences not distinguishable solely by using GETIN, including I think, Shift+Arrow keys. kbdbuf_get_modifiers have, however, not yet made it into the public Kernal API, even though there is a comment in the Kernal source saying that it should be. The calling address ($ca64) will probably change for each Kernal upgrade, so using this requires you to update your code when the Kernal changes. I did register an issue on the Kernal Github page, asking for kbdbuf_get_modifiers to be included in the API with a fixed jump vector. So far there has been no reaction to this. Link to the issue: https://github.com/commanderx16/x16-rom/issues/182 Finally, on the C64 it was still reasonable (?) to implement your own keyboard scan routines. On the X16 this is a lot more complex, especially with the support for different keyboard layouts. I have made a pull request on the Github page that would let you intercept the PS/2 scan codes before they are processed by the Kernal. It would work in a way similar to interrupts, letting you change a jump vector that calls your custom keyboard code. If this would make it into the Kernal, you could catch PageUp and PageDown scan codes (or any other scan code) and act on those keys. The beauty is that the rest of the Kernal keyboard routines would not need to be changed. But I haven't got any comments on the pull request either. Link to the pull request: https://github.com/commanderx16/x16-rom/pull/187
  14. I think you're right about that. This is said about the KOUNT variable ($028B) on https://www.pagetable.com/c64ref/c64mem/ I can't find that the KOUNT variable or any other similar variable is used by the X16 Kernal. Of coarse it could be there anyway. I have read somewhere that PS/2 keyboards managed key repeats themselves (generating multiple key down/up events I guess). Maybe the X16 Kernal is expecting that, which would make the keyboard repeat rate untweakable on the computer side. EDIT: I now realized that if you change the keyboard repeat settings in the host system, that also affects the repeat rating in the emulator. At least on MacOS. Am I right to assume that keyboard repeat rate is not handled by the Kernal? How would you set the repeat rate on the real machine? I searched a little for PS/2 keyboard hardware repeat rate, and found that there seems to be commands that you can send to the keyboard to change its default repeat rate setting. Maybe that's the answer.
  15. I'm in the process of cleaning the X16 Edit code. I still have some work to do, but I think it's very stable now. I couldn't resist implementing a new feature, as this was only about 20 lines of assembly - a prompt to execute DOS commands, for instance if you would like to rename or delete a file or create or rename a directory. This feature is not, however, not yet published. There are two issues that are a bit more complicated to solve One is the keyboard repeat rate. X16 Edit uses the Kernal keyboard routines, and it's sometimes painfully slow to wait for the cursor to move while you hold down an arrow key. The speed is the same as in the built-in BASIC editor, I would say. Is there anything you could do? If not, I might have to include more cursor movement features, maybe move one word back or forth. The other is the word-wrap feature. It is very simplified at the moment, and the feature I'm least satisfied with. Making it better is a large undertaking, though. Any thoughts on how to make it better without complicating the code base too much would be very appreciated.
  16. Very interesting. Hope you find the sources. I guess there is some tweaking to get those to work on X16. Wonder how much tweaking.
  17. This seems to work. Also puts out the blinking light. CLOSE = $ffc3 CLRCHN = $ffcc SETLFS = $ffba SETNAM = $ffbd OPEN = $ffc0 CHKIN = $ffc6 CHROUT = $ffd2 CHRIN = $ffcf READST =$ffb7 disk_status: lda #15 ldx #8 ldy #15 jsr SETLFS lda #0 jsr SETNAM jsr OPEN ldx #15 jsr CHKIN : jsr CHRIN pha jsr READST bne EOF pla jsr CHROUT bra :- EOF: pla lda #15 jsr CLOSE jsr CLRCHN rts
  18. Looks promising. You should probably use READST to check for errors/EOI instead of return value 0 from CHRIN. What happens when you run this?
  19. OK. READST just tells you that you have reached end of file or that there is some error, but not which one. By opening another file with secondary address 15 you may read the disk status text stream. The text stream is read with the same functions as a normal text file(call CHKIN, and then call CHRIN and READST in a loop until you get a non-zero status value). "00, OK, 00,00" is returned if there was no error. "62, FILE NOT FOUND,00,00" is returned on, you guessed it, file not found. There are, of coarse, many other possible disk errors. Read the complete list in the 1541 user manual page 42 found here: http://www.commodore.ca/wp-content/uploads/2018/11/commodore_vic_1541_floppy_drive_users_manual.pdf This is not entirely intuitive, being a Commodore legacy, when disk drives where almost computers of their own that you communicated with over the serial bus.
  20. Hi, The read loop in my program stops if READST returns anything else than 0. I have tested what return value you get from READST on file not found. And it is $42. That is $2 (time out read) + $40 (end of identity, sort of end of file). As your code tests for $40 that doesn't seem to explain your problem. To read the disk status, you need to open the command channel with a zero length file name. Otherwise you are effectively sending the file name to the drive which will try to interpret it as a DOS command. In most cases this will cause a syntax error, and the blinking continues. To see what I mean, try entering DOS "<anyfilename>" at the BASIC prompt. The blinking light turns on. Then read the status by entering just "DOS". You can see that the last error was syntax error. I haven't tested it, but you might actually also need to read the byte stream from the command channel before closing it in order to make the blinking light go away. Only by reading the stream, you get to know what disk error occurred, if that's of any interest to you. Finally, Greg and I discussed the order in which you should call CLOSE and CLRCHN some time ago. It's common to find C64 code examples online that first calls CLOSE and then CLRCHN. When testing this thourougly, I found that it doesn't matter in which order you call these functions. Having used X16 Edit for several months now, I have not had any file related problems with calling CLOSE first and CLRCHN second. I think you may rule out that this has anything to do with your problem.
  21. The blinking pixels at top right corner goes away after you read the disk status. In assembly, you need to open yet another file for reading with secondary address 15 (=command channel) to do this.
  22. OK. Please let us know if it solves your problem. Interesting issue after all.
  23. I haven't had that problem myself in my program X16 Edit. My program always reads the disk status after accessing a file, the equivalent of entering DOS at the BASIC prompt. Maybe reading the disk status is necessary, clearing the error state before accessing other files. It's not likely an emulator bug. More likely a "feature" of the Kernal that you stumbled upon.
  24. It looks nice, all simultaneously moving sprites. I have experienced SD card corruption if the SD card is mounted in the local file system at the same time it's used by the emulator. There's nothing stopping you from doing that, but you should avoid it.
  • Create New...

Important Information

Please review our Terms of Use