Odd behaviour when not PUSHing A writing to screen

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
Post Reply
User avatar
Thunor
Posts: 42
Joined: Sun Oct 11, 2009 11:37 am
Location: Anglia
Contact:

Odd behaviour when not PUSHing A writing to screen

Post by Thunor »

Hi

I've put together an asm file for cross-assembling and I've written a little test program within it. The test program prints 32x24 screenfulls of characters from space to Z but I was experiencing corruption and jerkiness which I fixed by saving and restoring the A register. It would appear that something is corrupting the A register with an invalid char value.

I'll post my code and the .p file and maybe somebody can explain what's happening.

Scroll down the code about half way and you'll see a PUSH AF and a POP AF lower down. If I comment these out the test will crash out very quickly, but left in I can add a "30 RUN" and run it forever without any problems.

[EDIT] Even more bizarre, if I replace the PUSH AF and POP AF by NOPs it works fine. I might have to fire up windows and try another emulator, or another assembler.

Code: Select all

; Start of the system variables area

ERR_NR          equ         0x4000
FLAGS           equ         0x4001
ERR_SP          equ         0x4002
RAMTOP          equ         0x4004
MODE            equ         0x4006
PPC             equ         0x4007

p_start:        org         0x4009

VERSN:          defb        0
E_PPC:          defw        20            ; BASIC line number of line with cursor.
D_FILE:         defw        display_file
DF_CC:          defw        display_file+1
VARS:           defw        variables
DEST:           defw        0
E_LINE:         defw        edit_line
CH_ADD:         defw        p_end-1
X_PTR:          defw        0
STKBOT:         defw        p_end
STKEND:         defw        p_end
BERG:           defb        0
MEM:            defw        MEMBOT
SPARE1:         defb        0
DF_SZ:          defb        2             ; Number of lines in lower part of screen.
S_TOP:          defw        20            ; BASIC line number of line at top of screen.
LAST_K:         defw        0xffff
DB_ST:          defb        0
MARGIN:         defb        0x37
NXTLIN:         defw        display_file  ; Memory address of next program line to be executed.
OLDPPC:         defw        0
FLAGX:          defb        0
STRLEN:         defw        0
T_ADDR:         defw        0x0c8d
SEED:           defw        0
FRAMES:         defw        0
COORDS:         defw        0
PR_CC:          defb        0xbc
S_POSN:         defb        0x21,0x18
CDFLAG:         defb        0x40
PRBUF:          defs        0x20
                defb        _NL
MEMBOT:         defs        0x1e
SPARE2:         defw        0

; Start of the BASIC area for user programs.

basic_0001:     defb        0,1    ; 1 REM
                defw        basic_0010-basic_0001-4
                defb        _REM

; Start of user machine code program vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

mem_16514:      xor         a            ; This is a simple screen test
                ld          b,0x40       ; of 64 frames of incrementing
l0:             push        bc           ; characters which should take
                push        af           ; around 2 seconds to complete.
                ld          hl,(D_FILE)
                inc         hl
                ld          b,24
l1:             push        bc
                ld          b,32
l2:             ld          (hl),a
                inc         hl
                djnz        l2
                ld          (hl),_NL-1   ; Here I'm simply keeping NL
                inc         (hl)         ; out of the REM statement so
                inc         hl           ; that it displays properly.
                pop         bc
                djnz        l1
                pop         af
                inc         a
                pop         bc
                djnz        l0
                ret

; End of user machine code program ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

                defb        _NL
basic_0010:     defb        0,10    ; 2 RAND USR 16514
                defw        basic_0020-basic_0010-4
                defb        _RAND,_USR,_1,_6,_5,_1,_4
                defb        0x7e
                defb        0x8f
                defb        0x01
                defb        0x04
                defb        0x00
                defb        0x00
                defb        _NL
basic_0020:     defb        0,20    ; 3 REM ** TYPE RUN **
                defw        basic_end-basic_0020-4
                defb        _REM,_EXP,_SPC,_T,_Y,_P,_E,_RUN,_EXP
                defb        _NL
basic_end:

; Start of the display file (synonymous with video memory)

; Expanded for > 3k RAM

display_file:   defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL
                defs        32
                defb        _NL

; Start of the variables area used by BASIC.

variables:      defb        0x80

; Start of the edit line used by BASIC.

edit_line:

p_end:          end
Attachments
mctemplate.p
(979 Bytes) Downloaded 211 times
mctemplate.asm
(5.03 KiB) Downloaded 201 times
User avatar
bobs
Posts: 325
Joined: Thu Aug 27, 2009 10:49 pm
Location: UK
Contact:

Re: Odd behaviour when not PUSHing A writing to screen

Post by bobs »

I've tested your code, and it works correctly for me running under EightyOne emulation, without the PUSH/POP AF.

The following is a bit weird:

Code: Select all

ld          (hl),_NL-1   ; Here I'm simply keeping NL
inc         (hl)         ; out of the REM statement so
inc         hl           ; that it displays properly.
Since that would essentially break the display buffer by having a non-newline character at the end of a line - maybe your emulator is constantly scanning the display buffer? Since you've pre-loaded the display buffer with a newline character at the end of each line, you can simply just use INC HL to skip over that character and to the start of the next line. I wouldn't worry too much about having the newline character in the REM statement either - in a full program you're probably not going to be able to avoid it.
User avatar
Thunor
Posts: 42
Joined: Sun Oct 11, 2009 11:37 am
Location: Anglia
Contact:

Re: Odd behaviour when not PUSHing A writing to screen

Post by Thunor »

bobs wrote:I've tested your code, and it works correctly for me running under EightyOne emulation, without the PUSH/POP AF.

The following is a bit weird:

Code: Select all

ld          (hl),_NL-1   ; Here I'm simply keeping NL
inc         (hl)         ; out of the REM statement so
inc         hl           ; that it displays properly.
Since that would essentially break the display buffer by having a non-newline character at the end of a line - maybe your emulator is constantly scanning the display buffer? Since you've pre-loaded the display buffer with a newline character at the end of each line, you can simply just use INC HL to skip over that character and to the start of the next line. I wouldn't worry too much about having the newline character in the REM statement either - in a full program you're probably not going to be able to avoid it.
Thanks for your help bobs.

It was the code above that you pointed out. Basically I was trying to be too clever and I screwed up :P If I just skip over the already existing end-of-line 0x76 it's perfectly stable, PUSH AF or not.

Interesting eh? Having a 0x75 there for a fraction of a second caused it to become unstable. Now I know I need to treat the D_FILE with more respect :)

Regards,
Thunor
Post Reply