HALT Right There!

Discussion about ZX80 / ZX81 Software
Post Reply
User avatar
GCHarder
Posts: 477
Joined: Sat Dec 14, 2013 7:46 pm

HALT Right There!

Post by GCHarder »

HALT RIGHT THERE!
By Fred Nachbaur

Syncware News v3n6 Jul.-Aug '86

An explanation of the Z80 HALT command.
Attachments
Halt.zip
Demo program
(2.36 KiB) Downloaded 194 times
David G
Posts: 632
Joined: Thu Jul 17, 2014 7:58 am
Location: 48 North

Re: HALT Right There!

Post by David G »

simple but intriguing

Then when I read the text and slowly realized what it is demonstrating

Code: Select all

1 REM _asm
     // Disassembly: 27 bytes @ $4082 (16514)
     L4082:  NOP     
             LD      HL,(400CH)
             LD      B,04H
      LOOP:  INC     HL
             LD      (HL),A
             DJNZ    LOOP
             RET 

     ;16525 entry point
     L408D:  LD      A,80H
             CALL    L4082
             LD      A,00H
             CALL    L4082
             CALL    $0F46  ;BREAK-2 ROM ROUTINE
             RET     NC
             JR      L408D
     END _asm
  10 POKE 16514,0
  20 RAND USR 16525
David G
Posts: 632
Joined: Thu Jul 17, 2014 7:58 am
Location: 48 North

Re: HALT Right There!

Post by David G »

i have already forgotten what it is demonstrating ... so i looked it over again and was still lost, but after experimenting it becomes clearer -- all part of the "experimenting" that Fred Nachbaur mentions

the program as delivered works best on a 60hz ZX81, it doesn't flash on the 50hz one. My ZX81 was bought from New York Sinclair, so it was set to 60hz. at 50hz, at least in the emulator, the display is partially drawn but not flashing. Changing the default line length to 5 makes a better demo at 50hz

here's the machine code. It repeatedly draws a short line of characters on the screen, then another line of spaces to blank it out. Kind of random flashing occurs until you poke in the HALT (118) to synchronize it to the display

Code: Select all

     drwLINE:NOP
             LD      HL,(D_FILE)
    numCHARS:LD      B,5                    ;number of characters to draw
        LOOP:INC     HL
             LD      (HL),A
             DJNZ    LOOP
             RET     

     FLASH_LINE:
             LD      A,80H                   ;'±' INVERSE SPACE
             CALL    drwLINE
             LD      A,00H                   ;' ' SPACE
             CALL    drwLINE
             CALL    $0F46                   ;BREAK_1_NEWROM
             RET     NC
             JR      FLASH_LINE
Works in FAST mode too, because it use the ROM call for BREAK. You can't see anything, but the BREAK key works. Since it is calling BREAK_1 in the improved ROM, running this on the original ZX81 "550" ROM hangs (BREAK doesn't work and the machine code just keeps running). But it tests OK with the BIGBANG "zx81x2" ROM


This is from the [Zx81:Type-Ins] "SyncWare News" campaign... 1985 July/August
HALT RIGHT THERE!
By Fred Nachbaur

Syncware News v3n6 Jul.-Aug '86

You ZX/TS users have been told, and told again, "Don't mess with the interrupts" and "Never use the HALT command." The severity of the admonitions seem to imply that a fate-worse-than-crashing awaits those who would tamper with such things.

Many TS2068 users already know that interrupt mode 2 can be quite useful; some of the better Spectrum games use this mode of operation. (See also Tom Woods' "Buggy Software" in a previous issue.) ZX/TSers, take heart; you too can experiment with such exotica, albeit on a more limited scale. The Z80 DI (disable interrupt) and EI (enable interrupt) commands are already in use in most "software hi-res" packages to help manage the hi-res display file.

That leaves the HALT command. When this command is encountered, the Z80 CPU stops running your program. In this way it is like the BASIC STOP command. More precisely, it endlessly executes NOPs (no operation) to keep memory refreshed. So far, it sounds like a pretty useless command, all right. However, your program will continue running after the HALT if the CPU receives an interrupt signal. The interrupt can thus be considered analogous to the BASIC CONT command.

In FAST mode, using the HALT command will most certainly cause the computer to "hang up", unless you supply an external INT signal to get it going again. In SLOW mode, however, the computer's logic chip continuously and automatically generates interrupt signals independent of the CPU. These are what are used to synchronize computer operation with your TV display. Whenever an interrupt occurs, the CPU stops what it's doing and goes off to 0038h to generate the TV picture. As a result, using the HALT command in SLOW mode will stop your program until the next TV frame has been completed.

By now, the usefulness of the HALT command in SLOW mode may be dawning on you. Clever use of this command can help to smooth out moving graphics by synchronizing them with the TV display.

As a demonstration see HALT.p

Enter RAND USR 16525, and you'll see a rapidly flashing bar at the top of the screen. Notice that, since the routine is not synchronized with the TV display, it looks choppy and "gappy." Stop the routine by pressing BREAK. Now, enter POKE 16514,118. This installs a HALT command at the start of the main printing subroutine. Again enter RAND USR 16525, and press BREAK when you tire of it. Notice how smooth it is now! The black bar (or the bar of spaces that erases it) is not printed until the computer finishes drawing the TV picture, resulting in smooth, consistent operation. POKE 16514,0 to restore it to original.

The time you are allowed depends on the "dead time" between frames less the overhead required by the NMI handling routine that counts the blank lines. If you're enterprising, you could figure this out by chasing down the NMI routine. But if you're lazy like me, you might prefer to experiment. You can change the number of spaces printed by the demo routine with a POKE 16519,N (N must be less than 33!) The time to print the bar (in T states) until the next HALT is 77+26*(N-1). The time to print the blanks is 109 T states higher because this is where we check for BREAK. I found that printing 5 spaces works, but printing 6 messes up the synchronization; this means that the maximum on the length of the routine is between 290 and 316 T states.

Thanks to James Hastings-Trew (Callisto Software) for pointing this out.
Post Reply