Martin (mvdzwan@syncnet.dmrt.nl) - Question:

 

>This little routine (I did not write it) can print to the screen in

>fast mode and lets you see it, it is a compromise between fast and

>slow so the screen flickers when this routine is used.

 

>Note: This routine will only make sense when used on a real ZX81/Timex 1000

 

>Perhaps someone here could explain how this routine works, I tried to put

>some comments and looked up the Rom Calls, but I do not really understand it.

 

 

 

wilf rigter (wrigter@dccnet.com) - Answer:

 

As requested here is a full explanation of the program listing you posted

including annotated references to the ROM code.

Note that, with exception of the START and BASIC routines, all this code runs

in the background as part of the interrupt driven video processing and sync

loop. In my comments I used the term PROGRAM to mean any "foreground" code

such as application programs other than the code in the background loop.

 

Actually, I simplified your program slightly for clarification and to keep the

focus on key elements.

 

 

*****************************************************************************

*START:       ;INSERT NEW VIDEO ROUTINES IN THE VIDEO DISPLAY LOOP

 

              ;Sinclair SLOW video routine sequence is altered by replacing

              ;parts with new video code.  

 

CALL 0F2B     SLOW COMMAND routine

              ;this is the functionally the same as: Set 6,(IY+4B) , JP 0207

LD IX,VID1    ;Save vector to START OF VIDEO DISPLAY routine

RET           ; return from USR call

 

               ***********************************************

               *    NEW INTERRUPT DRIVEN BACKGROUND LOOP     *

               ***********************************************

 

VID1:         ;START OF VIDEO DISPLAY routine

              ;similar to ROM routine @ 0282

              ;no comments in the ZX81 ROM DISASSEMBLY by IAN LOGAN

LD R,A        ;delay 7 T states (note the change to another 7 T instruction)

LD BC,1901    ;B = 24 character rows, C = 1 of 8 scanlines / CHR$ (wait 1 INT)

              ;experiment with B= 16 to 19 and C =  to 1  and note effect

              ;on start of the first row, truncated character height, rollover

LD A,F5       ;later transferred to R and determines the left edge of 1st row

CALL 02B5     ;START DISPLAY OF DFILE - see ROM code shown below

CALL ROM2     ;RETURN TO PROGRAM - see ROM code shown below

CALL ROM3     ;

LD IX,VID2    ;save vector to END OF DISPLAY routine

JP ROM4       ;ROM code at 02A4 shown below

 

*****************************************************************************

 

VID2:         ;END DFILE DISPLAY routine - similar to ROM routine @ 28F

 

              ;this contains the only piece of code that actually changes the

              ;original Sinclair SLOW mode. Note the large number of extra

              ;blank lines that are added to margin, providing 20 msec extra

              ;CPU time for the application program every vertical sync period.

              ;The display vertical frequency is actually 25 Hz but the TV

              ;displays this as two alternating/superimposed live and blank

              ;screens.  No wonder it runs faster and no wonder it flickers!

 

OUT (FD),A    ;Turn off the NMI generator

LD A,(4028)   ;get margin (A=1F)

ADD A,C2      ;1F+C2=E1

LD (4028),A   ;(MARGIN)=E1

CALL ROM2     ;Return to PROGRAM

CALL ROM3     ;save PROGRAM registers and process FRAMES, KEYBOARD and VSYNC

LD IX,VID1    ;Vector back to DISPLAY DFILE routine

JP ROM4       ;Return to PROGRAM

 

               **************************

               *   ZX81 ROM ROUTINES    *

               **************************

 

              ;ROM CODE @ 02B5 - DISPLAY DFILE ROUTINE

 

              ;Sets up R register and waits for interrupt (IAN LOGAN)

              ;Sets up R register, enables INT, JP (HL) to DFILE above 32K

              ;halts execution at first HALT of DFILE and waits for INT.

 

LD R,A        ;R increments with each M1 and is put on A0 to A7 during refresh

              ;When CPU HALTs at CHR$118, R continues to increment until A6

              ;goes low which causes an INT signal. (A6 is connected to INT)

              ;this ensures that the end of line timing is consistent also

              ;during a collapsed display when there may only be a HALT.

LD A,DD       ;Set the left margin of all other lines, loaded into R at 0041

              ;try E6 to shift screen right one character (change LD A,F5 too)

EI            ;Now that R is set up enable INT

JP (HL)       ;(rem HL = (DFILE)+32K) "executes" the DFILE starting with HALT

              ;and wait for the first INT to come to the rescue.

 

*****************************************************************************

 

              ;ROM CODE  @ 0292 - RETURN TO PROGRAM ROUTINE

 

              ;IX is loaded with "return" address and main registers restored

              ;after a slow display (IAN LOGAN)

              ;Save return address of live display or vertical sync interval

              ;routines in IX , PROGRAM registers are restore ( which were

              ;previously saved when PROGRAM was interrupted for by NMI @ 0066

              ;and NMI-CONT @ 006F) and finally RETURNs to PROGRAM execution,

              ;interrupted every ~ 64 usec by NMI until AF'= 0

 

POP IX        ;Normally IX=0281 or 028F to flip between DISPLAY and VSYNC

              ;in this case IX=VID1 or VID2 to execute special video routines

LD C,(IY+56)  ;load number of blank lines from MARGIN (1F in 60 Hz option)

BIT 7,(IY+59) ;test FAST/SLOW bit

JR Z,2A9      ;never branches in SLOW mode

LD A,C        ;LD A,(MARGIN) (MARGIN contains 1F for 60 Hz)

NEG           ;A=E1

INC A         ;A=E2  which means 30 blank lines above and below the display

EX AF,AF'     ;during NMI @ 0066 - AF' is incremented and tested for zero

OUT (FE),A    ;turn on NMI generator in ULA which interrupts every 64 uSec.

POP HL        ;self explanatory

POP DE

POP BC

POP AF

RET           ;returns to program later interrupted by NMI and NMI-CONT

 

*****************************************************************************

 

              ;ROM CODE @ 0220 - VERTICAL SYNC INTERVAL PROCESSING ROUTINE

             

PUSH AF       ;save PROGRAM main registers

PUSH BC

PUSH DE

PUSH HL

JP 0229       ;Jump to long complicated Sinclair ROM segment not copied here

              ;decrement FRAME counter, read the keyboard, generate vertical

              ;sync and end with CALL 0292 to return PROGRAM

 

*****************************************************************************

 

              ;ROM CODE @ 02A4

 

POP HL        ;self explanatory

POP DE

POP BC

POP AF

RET           ;return to program interrupted by NMI and NMI-CONT

 

*****************************************************************************

 

Here is a simplified basic routine to test it:

 

   1 REM "PUT HERE THE MACHINE CODE"

 

  10 FOR A=1 TO 21       ;fill the screen

  20 PRINT "TEST OF NEW SLOW MODE VIDEO EXPERIMENTS"

  30 NEXT A              ; with 22 rows of characters

  40 RAND USR 16516      ; call new slow display mode

  50 GOSUB 100           ; delay and display 0 to 9

  60 SLOW                ; flip back to Sinclair slow mode

  70 GOSUB 100           ; delay and display 0 to 9

  80 GOTO 40             ; loop indefinitely

 

  100 FOR N= 0 TO 9      ; delay loop used to measure execution time

  110 PRINT AT 21,13;N   ; real-time count display

  120 NEXT N

  130 FAST               ; effectively LD IX, 0281 to escape from VID1/2

  140 RETURN