Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

12 hours ago, dhe said:

While re-re-reading the E/A manual, I was noticing this section on the Debugger, descended from TIBUG, and came upon this paragraph.

 

Causes the present VDP Read Data address to be displayed. The address can be altered by typing a
new address and pressing ENTER. This procedure allows you to use the commands that access VDP
to be used in the VDP library memory areas or any other VDP address space. The read and write
addresses are >1000 apart. The default address is >8800. Note: At present, no alternate VDP memory
spaces exist.

 

I can see alternate read/write address writing to a different bank of 16K VDP memory. I don't see a path forward in getting the VDP to change to another bank. I also, don't know what a VDP Library Memory is.  Can anyone fill out what TI was thinking about doing?

Could be they were considering something along the lines of GROM banking - every four bytes accessing a different bank of GROM. The same is feasible with the VDP for up to 256 VDPs in the current reserved space. That's what I want to see, Gary. ;)

 

The issue with the banking is the same as for the GROMs, it's not fully decoded on the motherboard, so you have to add the hardware to split up the address space. Not too complex for a few though.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

13 hours ago, Gary from OPA said:

I always wanted to make a mod and try, but there was an idea once to have multiple vdp processors, the tms9918a can infact have the video out go into the video in. So you have two vdp chips each with their own 16k and when you use the transparent color on the master chip those pixels display the data from the secondary vdp processor.

 

I will see if I can upload the datasheet design spec later on this weekend in a new thread for this application of multiple screens, useful to expand the depth and graphics like for multi layer sprites, but it was never done to my knowledge just drafted out on paper as a design idea.

The main trick IIRC with it is you need to get a high voltage pulse on sync into the sync/reset line. I don't think the circuit is documented, only the concept...

 

The datasheet I have backs up my memory -- you have to drive the RESET pin above 9V (Recommended is listed as 10-12V) for external sync. Which means you need to extract sync from the previous VDP's composite output (rated as 1.85-2.1V), raise it cleanly, and juggle it with the console reset line. Honestly the 9928's approach of just signaling an external video switch seems easier. ;)


That said, when I played with the video input line many, many years ago, I actually just cut the reset line (with the intent of figuring it out later) and fed in composite video from a VCR. Everything /worked/ technically, switching, overlay, but it was useless without the sync of course... When the 9918A was in charge, there was slight bleed-through from the VCR, out of sync of course. The balancing circuit would probably solve that.

When I switched on external video from the VDP register, the VCR input took over sync and was stable, but without sync pulses, the VDP was now out of sync. It was clearly superimposed, though!

 

Radio Electronics did an article on making a titler out of a 9918 and using the video overlay feature, so in theory all the needed information and circuitry are in there. I've saved the article all these decades out of interest of seeing it someday. Their job was a little more complex since they needed to take a slightly incompatible external video signal, but stacking VDPs you should be able to assume they are starting pretty damn close. ;)

 

(edit: All these years I've been sharing the wrong issues - turns out R-E did video titlers /twice/. The first was just for generating text screens. The SECOND was the TI-based overlay one. BUT... my brain remembered wrong (and young me in 1985 probably misunderstood)... it does use the 9928 and externally switches the video, it does not use the internal mixer. BUT, it still needs to generate that SYNC pulse, so there is still valuable info in here.

Also, my archived scans are terrible quality...)

 

Radio-Electronics-1985-11.pdf Radio-Electronics-1985-12.pdf Radio-Electronics-1986-01.pdf Radio-Electronics-1986-03.pdf

Edited by Tursi
  • Like 4
  • Thanks 1
Link to comment
Share on other sites

4 hours ago, Gary from OPA said:

As for why TI uses small caps, I think it's mainly from their earlier days of being a calculator company before they got into computers...

No it's not, because it was in the logotype from day one, in 1951, when it changed name from Geophysical Service Incorporated. There were no calculators around back then.

 

Regarding the external video, as far as I remember it's only in the NTSC version, TMS 9918, not in the other versions 9928 and 9929.

  • Like 1
Link to comment
Share on other sites

46 minutes ago, apersson850 said:

No it's not, because it was in the logotype from day one, in 1951, when it changed name from Geophysical Service Incorporated. There were no calculators around back then.

 

Regarding the external video, as far as I remember it's only in the NTSC version, TMS 9918, not in the other versions 9928 and 9929.

Yeah, that is true. We might never know why they were using small caps from their early days of making mining industrial electronics machines.

 

There is a whole Wikipedia page about the history of small caps: https://en.m.wikipedia.org/wiki/Small_caps

 

As for the video processing stacking the tms9918 a bit easier as the overlay circuit is inside the silicon but all versions can handle it, even the later improved models of v9938 had that option.

 

On the ti99 when using the 9918 the extvdp is infact sent to pin 5 of the monitor part, but as @Tursi points out the SYNC line is fixed to the reset control stuff the missing pull to 9v circuit is not there, plus it has to be timed right as if you pull it for too long the vram stops being refreshed as well, causing data loss.

 

I need to find the original ti datasheet that shows how it all works they made what was called a "application note" describing it in detail with the special 9v sync circuit detailed out.

Edited by Gary from OPA
  • Like 1
Link to comment
Share on other sites

What I usually see here used instead of small capitals are italics. For the same reason as the Wikipedia article mentions as a use case for small capitals.

When I do see small capitals here it's in that case as the first few words in a new paragraph. Instead of indentations or just one large leading letter. But then they aren't small capitals in the font used, but a totally separate font used for the leading words. Sometimes even in a different color.

  • Like 1
Link to comment
Share on other sites

As for some trivia in between, some time ago I learned that "case" still refers to the set of letters of the typesetter, when the typesetter had one case (the upper case) with the capitals sorted in, and another one below with the small letters. Although Gutenberg invented the printing press, we don't have a similar (known) term in German, just "big letter" and "small letter".

 

By the way, the lower case letters are from medieval times (8th century), and the capitals, of course, from the Romans.

 

I also learned that in Arabic, you have four "cases": starting, middle, ending, and isolated.

 

  • Like 3
Link to comment
Share on other sites

 I think I found another pesky bug in the E/A manual.

 

PG 348

 LI R0,>81E1
   BLWP @VWTR     Load VDP Register to magnify sprites.

I think this needs to be:
   LI R0,>01E1
   BLWP @VWTR    
 

 

I think first byte in a vwtr needs to be 0-7?

  with the first byte being the register, and the second byte being the data for that register.

Link to comment
Share on other sites

16 minutes ago, dhe said:

 I think I found another pesky bug in the E/A manual.

 

PG 348

 LI R0,>81E1
   BLWP @VWTR     Load VDP Register to magnify sprites.

I think this needs to be:
   LI R0,>01E1
   BLWP @VWTR    
 

 

I think first byte in a vwtr needs to be 0-7?

  with the first byte being the register, and the second byte being the data for that register.

yeah it is bug, but in the end VWTR changes the bit anyway to >8xxxx to tell the VDP it is register command not a 'write' data command.

 

********************************* REGS PASSED= R0 MSByte = VDP REG #
* VWTR = Video Write to Register*                 LSByte = DATA BYTE
*********************************
VWTR   DATA UTILWS,VWTR1
VWTR1  BL   @VDPSWR
       RTWP
 
VDPSWR MOV  *R13,R0           USE BY ALL THE ABOVE VIDEO BLWP's
       ORI  R0,>8000
       JMP  VDPGO
VDPSWA MOV  *R13,R0
VDPSTW ORI  R0,>4000
       JMP  VDPGO
VDPSRA MOV  *R13,R0
VDPGO  MOVB @UTILWS+1,@VDPWA
       MOVB R0,@VDPWA
       MOV  @2(R13),R1
       MOV  @4(R13),R2
       RT

 

So they are partly right as that is what will happen in the end.

  • Like 4
Link to comment
Share on other sites

Mildly interesting to me, as I've never played with the TITL or IDT Assembler Directives.

 

*
* Example program to make a crash sound
*
       TITL 'MY_TITLE'
       IDT  'MY_IDT'
 
       REF VMBW
       DEF CRASH
*
BUFFER EQU >1000 VDP RAM buffer used by
*                       Sound generator
*
H01    BYTE >01
       EVEN
*
CRASH
       LI R0,BUFFER     Load VDP RAM buffer address.
       LI R1,CDATA      Pointer to the sound data.
       LI R2,32         32 bytes to move to the VDP RAM buf
       BLWP @VMBW       Move to VDP RAM buffer.
*
LOOP
       LIMI 0           Disable VDP interrupt.
       LI R10,BUFFER    Load sound table address.
       MOV R10,@>83CC   Load pointer to the table.
       SOCB @H01,@>83FD Set VDP RAM flag.
       MOVB @H01,@>83CE Start sound processing.
       LIMI 2 Enable    VDP interrupt.
*
LOOP2
       MOVB @>83CE,@>83CE Check if time is up
       JEQ LOOP           Finished with the sound table.
       JMP LOOP2          Wait until finished.
*
CDATA  BYTE >03,>9F,>E4,>F2,5
       BYTE >02,>E4,>F0,12
       BYTE >02,>E4,>F2,10
       BYTE >02,>E4,>F4,8
       BYTE >02,>E4,>F6,6
       BYTE >02,>E4,>F8,4
       BYTE >02,>E4,>FA,2
       BYTE >01,>FF,0
 
       END

 

Results In:

00058MY_IDT  A0000B0100B0200B1000B0201C0038B0202B0020B0420B00007F274F       0001
A0012B0300B0000B020AB1000BC80AB83CCBF820C0000B83FDBD820C00007F2C6F          0002
A0028B83CEB0300B0002BD820B83CEB83CEB13EEB10FBB039FBE4F2B05027F23BF          0003
A003EBE4F0B0C02BE4F2B0A02BE4F4B0802BE4F6B0602BE4F8B0402BE4FA7F21BF          0004
A0054B0201BFF007FC8CF                                                       0005
30010VMBW  50002CRASH 7FAD1F                                                0006
:       99/4 AS  

 

 

.
 99/4 ASSEMBLER
MY_TITLE                                                     PAGE 0001
  0001            *   
  0002            * Example program to make a crash sound   
  0003            *   
  0005                   IDT  'MY_IDT'  
  0006                
  0007                   REF VMBW   
  0008                   DEF CRASH  
  0009            *   
  0010      1000  BUFFER EQU >1000 VDP RAM buffer used by   
  0011            *                       Sound generator   
  0012            *   
  0013 0000   01  H01    BYTE >01   
  0014                   EVEN   
  0015            *   
  0016            CRASH   
  0017 0002 0200         LI R0,BUFFER     Load VDP RAM buffer address.  
       0004 1000  
  0018 0006 0201         LI R1,CDATA      Pointer to the sound data.  
       0008 0038' 
  0019 000A 0202         LI R2,32         32 bytes to move to the VDP RAM buf 
       000C 0020  
  0020 000E 0420         BLWP @VMBW       Move to VDP RAM buffer.   
       0010 0000  
  0021            *   
  0022            LOOP  
  0023 0012 0300         LIMI 0           Disable VDP interrupt.  
       0014 0000  
  0024 0016 020A         LI R10,BUFFER    Load sound table address.   
       0018 1000  
  0025 001A C80A         MOV R10,@>83CC   Load pointer to the table.  
       001C 83CC  
  0026 001E F820         SOCB @H01,@>83FD Set VDP RAM flag.   
       0020 0000' 
       0022 83FD  
  0027 0024 D820         MOVB @H01,@>83CE Start sound processing.   
       0026 0000' 
       0028 83CE  
  0028 002A 0300         LIMI 2 Enable    VDP interrupt.  
       002C 0002  
  0029            *   
  0030            LOOP2   
  0031 002E D820         MOVB @>83CE,@>83CE Check if time is up   
       0030 83CE  
       0032 83CE  
  0032 0034 13EE         JEQ LOOP           Finished with the sound table.  
  0033 0036 10FB         JMP LOOP2          Wait until finished.  
  0034            *   
  0035 0038   03  CDATA  BYTE >03,>9F,>E4,>F2,5   
       0039   9F  
       003A   E4  
       003B   F2  
       003C   05  
  0036 003D   02         BYTE >02,>E4,>F0,12  
       003E   E4  
       003F   F0  
       0040   0C  
  0037 0041   02         BYTE >02,>E4,>F2,10  
       0042   E4  
       0043   F2  
.
 99/4 ASSEMBLER
MY_TITLE                                                     PAGE 0002
       0044   0A  
  0038 0045   02         BYTE >02,>E4,>F4,8   
       0046   E4  
       0047   F4  
       0048   08  
  0039 0049   02         BYTE >02,>E4,>F6,6   
       004A   E4  
       004B   F6  
       004C   06  
  0040 004D   02         BYTE >02,>E4,>F8,4   
       004E   E4  
       004F   F8  
       0050   04  
  0041 0051   02         BYTE >02,>E4,>FA,2   
       0052   E4  
       0053   FA  
       0054   02  
  0042 0055   01         BYTE >01,>FF,0   
       0056   FF  
       0057   00  
  0043                
  0044                   END  
  0000 ERRORS

 

If you look closely and read between the lines, you can always see DX-10/TM990 influences.

 

Also, as you can see, TI just made the default TITL = 'VERSION 1.2', because if YOU use TITLE, the TITLE you give is substituted for 'VERSION 1.2'.

 

image.png.3962c886c661ba9b6db7c76aa95f069e.png

 

  • Like 1
Link to comment
Share on other sites

20 hours ago, apersson850 said:

I'm talking about the reason for why they used that font also in the TMS 9918A manual. The origin of it. And that's pretty clear. They didn't know any better since they already had it in their logotype.

Yeah you've got all the evidence right there. Right there in front of whoever  designed  the chars. 
 

Still, they knew how to make lower case in dot matrix. 
 

But from memos I see, their world was usually devoid of lower case. MEMOS WERE WRITTEN IN ALL CAPS.  I speculate that all online messages traveled through IBM mainframe in EBCDIC with no lower case. 

 

  • Like 1
Link to comment
Share on other sites

Things  that don't have lowercase at all:

 

99/4 of course

Punch tools for cards, except with "multipunch" keys

Line printers with 60 chars on rotating drum

Many teletypes and dumb terminals

BCDIC

Paper tape

Programming languages until late 70s

Any 6- bit communication link

 

 

I looked up IBM stuff:

 

IBM System/360

     BCDIC    EBCDIC    Punch Card          Tape
      HEX       HEX      HOLES            (binary) 
SPACE  40       40       none              
a-i   n/a     81-89     12- 0-1   to 9      n/a
j-r   n/a     91-99     12-11-1   to 9      n/a
s-z   n/a     A2-A9     11-0-2    to 9      n/a

A-I  C1-C9    C1-C9     12-1 to 12-9      110001 to 111001
J-R  D1-D9    D1-D9     11-1 to 11-9      100001 to 101001
S-Z  E2-E9    E2-E9      0-2 to 0-9       010010 to 011001
0-9  F0-F9    F0-F9       0  to 9         001010 for 0
                                          000001 to 001001

 

 

 

  • Like 1
Link to comment
Share on other sites

10 minutes ago, mizapf said:

Could refer to the common segment handling (CSEG, CEND). As we don't have a loader that processes common segments, it serves no purpose for us.

at some point, i will finish my old project of making a better loader and assembler that handles larger memory spaces using all the currently unused tags that exist in the system would be great for those wishing to write large SAMS programs in assembly.

 

But I think you right it has to do with having too many "common" segments in the object file, alot of it left over from the DS-990 assembler.

Link to comment
Share on other sites

20 hours ago, dhe said:
CRASH
       LI R0,BUFFER     Load VDP RAM buffer address.
       LI R1,CDATA      Pointer to the sound data.
       LI R2,32         32 bytes to move to the VDP RAM buf
       BLWP @VMBW       Move to VDP RAM buffer.
*
LOOP
       LIMI 0           Disable VDP interrupt.

 

It is never safe to write to the VDP with interrupts enabled.  You need to have a `LIMI 0` sometime before you call `BLWP @VMBW`.

  • Like 1
Link to comment
Share on other sites

On 4/26/2024 at 5:41 PM, mizapf said:

Although Gutenberg invented the printing press, we don't have a similar (known) term in German, just "big letter" and "small letter".

In Swedish it's versaler and gemena. Or like in German, just big and small.

Link to comment
Share on other sites

5 hours ago, matthew180 said:

 

It is never safe to write to the VDP with interrupts enabled.  You need to have a `LIMI 0` sometime before you call `BLWP @VMBW`.

Not a popular idea but here is what I did. @dhe

I put my LIMI 0, in my address setter sub-routine. There is one entry for writing (ORing a register with >4000) WMODE  and another entry for reading, RMODE.

It slows it down, but it's always in the right place. :)

 

At the end of  each VDP routine I re-enable interrupts.

This allows me to do sprites and motion interactively from the interpreter which is pretty fun. 

 

In the for what it's worth department...

 

It's all in RPN Assembler but if you feel the need to read code while hanging from the ceiling upside down here it is. 

 

CAMEL99-ITC/Compiler/cc9900/SRC.ITC/TI99IOX.HSF at master · bfox9900/CAMEL99-ITC · GitHub

  • Like 2
  • Haha 1
Link to comment
Share on other sites

5 hours ago, matthew180 said:

 

It is never safe to write to the VDP with interrupts enabled.  You need to have a `LIMI 0` sometime before you call `BLWP @VMBW`.

You only need to put the limi 0 inside the blwp before the VDP write that is the best place for it, as it will turn off interrupts and when the RTWP executes the interrupts will be restored how they were before bring either limi 2 or something else.

 

That way you don't have to worry about what state they were when you get called, that the beauty of context switching with blwp as it backups the status register into r15, leaving you free to turn off or even enable interrupts inside your routines and then on exit it gets restored back the way they were as r15 gets put back into the status register.

  • Like 4
  • Thanks 1
Link to comment
Share on other sites

2 hours ago, Gary from OPA said:

You only need to put the limi 0 inside the blwp before the VDP write that is the best place for it, as it will turn off interrupts and when the RTWP executes the interrupts will be restored how they were before bring either limi 2 or something else.

 

That way you don't have to worry about what state they were when you get called, that the beauty of context switching with blwp as it backups the status register into r15, leaving you free to turn off or even enable interrupts inside your routines and then on exit it gets restored back the way they were as r15 gets put back into the status register.

That sounds very good. I may fool around with that. 

I don't use BLWP for setting VDP addresses because its a leaf and a fast BL seemed all I needed

I reserve full context switching for task switching in my system.

With a return stack implemented it not a big deal to save a register or two if you are short somewhere but so far I find with passing parameters on the data stack and 6 scratch registers I have never needed to push/pop registers. 

YMMV as they say.  

 

But if I understand you correctly I can READ VDP without worrying about using LIMI 0 ??

Link to comment
Share on other sites

34 minutes ago, TheBF said:

That sounds very good. I may fool around with that. 

I don't use BLWP for setting VDP addresses because its a leaf and a fast BL seemed all I needed

I reserve full context switching for task switching in my system.

With a return stack implemented it not a big deal to save a register or two if you are short somewhere but so far I find with passing parameters on the data stack and 6 scratch registers I have never needed to push/pop registers. 

YMMV as they say.  

 

But if I understand you correctly I can READ VDP without worrying about using LIMI 0 ??

It is best to disable it when setting up the address. Either read or write, or writing a register, anything that requires two byte command to the VDP.

 

Quote

 
   

You will have noticed that commands are 2-byte long. The VDP maintains an internal flag to know whether the first byte has already arrived. Once the second byte arrives, the command is executed. It is of importance to realize than any access to the data port (>8800 or >8C00) or to the status port (>8802) will reset this flag. This was probably done so that you can put the VDP in a known state in case something went wrong with programming: otherwise the only way to reset the byte flag would be a hardware reset! This is why interrupt must be disabled during VDP operations: since the interrupt service routine accesses the VDP it would cancel any pending command if an interrupt occured in-between the two bytes.

 

https://www.unige.ch/medecine/nouspikel/ti99/tms9918a.htm

 

Even if you not playing a sound or having sprite auto motion running, the interrupt routine still reads the VDP status each time which causes the VDP to reset so if you in the middle of setting up a read or write address and am interrupt occurs you are screwed.

Edited by Gary from OPA
  • Like 2
Link to comment
Share on other sites

5 hours ago, Gary from OPA said:

Even if you not playing a sound or having sprite auto motion running, the interrupt routine still reads the VDP status each time which causes the VDP to reset so if you in the middle of setting up a read or write address and am interrupt occurs you are screwed.

Thanks Gary.

 

Reading all the TI docs I can get my hands on, and also, all the 'learn' assembly language manuals, ALL of them just seem to kind of mumble their way through the interrupt routes, CRU stuff as well as X and XOP seem to get short shift. Solid nuggets like the one above really help clarify what is happen and why.

Link to comment
Share on other sites

49 minutes ago, dhe said:

Thanks Gary.

 

Reading all the TI docs I can get my hands on, and also, all the 'learn' assembly language manuals, ALL of them just seem to kind of mumble their way through the interrupt routes, CRU stuff as well as X and XOP seem to get short shift. Solid nuggets like the one above really help clarify what is happen and why.

Yeah, most manuals and guides skip over the nitty gritty stuff. For example the X instruction, not much info on it, but TI themselves used it a lot, as it is handy to do things like bytewide interpret code, for example their GPL and Basic in the console ROM you will find the X used often with tables of different opcodes. And also used on things like the FDC DSR etc.

 

Quote

The TMS9900 supports an execute instruction "X" (eXecute). This instruction executes the instruction in a register. It can be used for debugging (as a breakpoint instruction), for creating indexed-opcode tables as used in byte-code interpreters and can also be used to perform a time critical I/O instruction during an interrupt. An example of its utility is shown in the code below where an interrupt being serviced in a very encapsulated manner that would otherwise require many more instructions.

 

This example of common piece of code below during a possible interrupt routine that can be used by both I/O read and write commands.

 

Similar methods could be employed in any debugging methods wanting to be used.

 

https://en.m.wikipedia.org/wiki/TMS9900

;***********************************
;
;	THIS INTERRUPT SIMULATES DMA CONTROL
;	ORGANISED AS FOLLOWS:
;
; R9 HOLDS CURRENT COMMAND, E.G.
;   IOREAD:  STCR	*R8+,BYTEWIDE	;BYTE WIDE FDC DATA READ
;   IOWRITE: LDCR	*R8+,BYTEWIDE	;BYTE WIDE FDC DATA WRITE
; R8 HOLDS THE CURRENT DMA ADDRESS.
; R12 HOLDS THE CURRENT IO PORT - DATREG
;************************************
INTDRQ	X	R9	;CAN BE EITHER READ or WRITE 
        RTWP

 

  • Like 3
Link to comment
Share on other sites

9 hours ago, dhe said:

Reading all the TI docs I can get my hands on, ...

 

I hope that includes the first 40 pages of this thread.  They pretty much cover everything in detail, no hand waving or mumbling around topics.  The second 40 pages are mostly a rehash of the first 40 pages.

 

8 hours ago, Gary from OPA said:

Yeah, most manuals and guides skip over the nitty gritty stuff.

 

Sometimes it is hard to give an answer without slipping into some lower level detail.  There is a lot of nuance at the hardware layer that leaks over into the assembly layer.  The first thing people try to do is put abstractions on top of these details in an attempt to make the system easier to use.  But there are trade-offs, as there always are.  The hardest part about assembly language is not assembly language; it is understanding the system upon which you are trying to write code for.

 

14 hours ago, Gary from OPA said:

Even if you not playing a sound or having sprite auto motion running, the interrupt routine still reads the VDP status each time which causes the VDP to reset so if you in the middle of setting up a read or write address and am interrupt occurs you are screwed.

 

If the console ISR is allowed to run at all, for any reason, *every time* you want to do *anything* with the VDP you have to disable interrupts, set up the VDP address, read / write your data, and re-enable interrupts.  And if the console ISR runs and you need VDP status in your own program, you have to get it from the dedicated location in scratch-pad (I don't remember the exact address) where the ISR stores a copy of the VDP status.

 

@dhe The VDP can only receive one byte at a time.  It takes two writes to the VDP to set up its internal address register, and reading the VDP status will reset that sequence.  The 9900 (and most CPUs) will check for interrupts between instructions.  This means if CPU interrupts are enabled, your code can be interrupted between any instructions in your program.

 

If you are in the middle of the sequence to set up the VDP's address register, and the interrupt fires and does any communication with the VDP, then it will wreck your sequence and the VDP address register will not be set.

 

Also, if you have set the VDP address register and are now in the process of reading / writing VRAM when the interrupt fires, and if the ISR is set to auto-play sound or process sprite motion, then it will change the VDP address register to what it needs and read / write VRAM.  When your code resumes, you are now reading / writing to the wrong VRAM location.

 

In the 9918A Datasheet, pg 2-1, section 2.1.2, along with a big NOTE.  The 9918A Datasheet was not laid out very well, but the info is in there, it just takes some focused reading and taking lots of notes.

 

What you don't get from the datasheet is the interplay between your code, the console ISR, and the VDP.  This is why I really like to turn off the console ISR, and recommend for people learning to do the same.  The VDP is very straight forward, and reinventing VSBW, VMBW, etc. on your own is part of learning.  All the console ROM and GROM abstraction routines are usually thought of as helpers, however if you don't know the details of what they are doing and all the details about the ISR and such, they can be foot-guns when trying to get started and just do some simple things like putting graphics on the screen.

 

IMO, the simple way to co-exist with the ISR:

START
    LIMI 0

. . . Init code . . .

MAINLOOP

. . . All your code . . .

    LIMI 2
    LIMI 0
    B @MAINLOOP

 

Allow interrupts once in your main loop, in a very controlled place.

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...