11

In my early days, many many years ago, one of the machines I managed to get my hands on was the COMX-35, a funky little machine based on the 1802 CPU.

Picture of a COMX-35 from Wikipedia

I remember trying to develop some games for it and, as part of that process, I attempted to use 1802 assembler code to write directly to the screen rather than relying on the interpreted BASIC. From memory, the video RAM was supposed to be located at a fixed address.

However, try as I might, I could not get characters to reliably show up on the screen by simply injecting them into those memory locations. There was some success but it seemed to be very intermittent.

I ended up writing the program (Four In A Row) in BASIC and it was rather slow, particularly the animation of the tiles falling into the board (good enough to keep my mother amused however).

I was wondering if anyone knew why my attempts were spurious at best.


Addendum:

Regarding the possibility of the hardware scrolling, I'm not sure that was the case. From memory, running my program immediately after boot/load-from-tape, when no scrolling had taken place, was problematic.

And, once running, it was still intermittent - I wouldn't have thought scrolling would take place if my code was just poking memory and not using any regular things like print statements. Still, I haven't seen the ROM so can't discount this totally.

4
  • 3
    The wikipedia article mentions it hard a hardware scrolling capability: "The screen had 960 characters where position 0 (left top corner) could be accessed by memory location @F800 (before scrolling)." Commented Apr 6, 2022 at 1:11
  • 1
    There is also an emulator, and I'd assume the ROM is in there, if someone wants to look at scrolling in more detail.
    – dirkt
    Commented Apr 6, 2022 at 6:29
  • 1
    Another thing to check: Was something else (like, say, a ROM routine triggered by a timer interrupt) trying to write to screen memory at the same time? Commented Apr 6, 2022 at 9:03
  • 1
    Actually, investigations over the last day or so have borne fruit. Turns out the display memory is only accessible about 1/3 of the time (call this allowed time). The way in which the ROM output characters is rather clever, buffering them during the disallowed time then, when an interrupt marked the start of allowed time, it would blast the buffered characters out in one hit. I've added an answer to (hopefully) better explain this.
    – paxdiablo
    Commented Apr 7, 2022 at 12:01

2 Answers 2

13

According to the COMX-35 Wikipedia entry (my emphasis):

The VIS [Video Interface System] ran on 5.626 MHz for a PAL and 5.67 MHz for an NTSC machine. This frequency was divided by 2 and output via CPUCLK (pin 38) to the CDP 1802 for timing of the CPU (2.813 and 2.835 MHz).

The VIS was also responsible for the timing of the interrupt (50/60 Hz) and timing of the non-display period via PREDISPLAY (pin 1).

Video memory could only be accessed during the non-display period which allowed for execution of 2160 machine cycles on a PAL and 1574 on an NTSC machine. Provided that not more instructions were executed than the indicated maximum number of machine cycles video memory could be accessed during the interrupt routine.

Alternatively the program could be paused by waiting for a non display period by checking EF1.

This is confirmed in the COMX-35 Technical Reference Manual in the section dealing with display memory` (paraphrased):

This area is write-only and can only be accessed during the
non-display period. The program may wait for the non-display
period and directly write to this area:
    B1   $    ; Await non-display period (via EF1).
    STR  R7   ; write to the area.

So that seems to account for the unreliability. It's not enough to just poke values into that memory at any time. The non-display period only forms a portion of the actual time (about 1/3 according to this site but I'm not sure this is a real problem, see below) so you had to use the method shown to ensure the bytes were written successfully.

The write-only nature probably also complicates things as you can't check to see if the value you wrote is there.


That same technical reference manual shows an interesting approach to screen updates:

In COMX-35, the display output routine does not access the screen memory directly. Instead, the output characters are buffered in a FIFO memory. Interrupts are generated by the PREDISPLAY' signal (50/60Hz). The interrupt routine will flush the output characters in the FIFO memory into the page memory at the appropriate screen location.

So, it wouldn't write every individual character after waiting around until EF1 says it can be written - that could slow things down considerably if, for example, every time you wanted to write a character, you had just ended the "allowed to write" state.

Instead, multiple characters were buffered without any delays, then written as a unit in the interrupt routine called when PREDISPLAY' activates.

Of course, you would have to be certain that a PREDISPLAY' period was long enough to clear the largest buffer that could be created outside that period, otherwise the queue may eventually fill up to the point where you have to start waiting.

5

The wikipedia article says that the video interface system consists of CDP1869/CDP1870. The data sheet of the CD1869 states on p.377 that the "Out 7" instruction could be used for scroll operations:

The instruction uses 9 data bits to load the home-address register bits [...] The home-address register outputs are transferred to the refresh-address counter at the end of each display frame.

So as Greg Hewgill remarked in the comment, the most likely reason you were not able to "reliably" inject them into memory locations was because you didn't take scrolling into account, and the "intermittent" success occurred when the scroll origin was reset.

3
  • I'm not sure that was the case. From memory, running my program immediately after boot/load-from-tape, when no scrolling had taken place, was problematic. And, once running, it was still intermittent - I wouldn't have thought scrolling would take place if my code was just poking memory and not using any regular things like print statements. Still, I haven't seen the ROM so can't discount this totally.
    – paxdiablo
    Commented Apr 6, 2022 at 6:12
  • Please also update your question with any additional information like this - it will make it simpler to answer your question.
    – dirkt
    Commented Apr 6, 2022 at 6:25
  • dirkt, done. I'm not saying this isn't the case, just that my memory doesn't gel with it, but that could well be my memory :-) So here's an upvote for at least the possibility.
    – paxdiablo
    Commented Apr 6, 2022 at 7:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .