FAQ  •  Register  •  Login

SPECTRA Advanced Graphics - Assembly

<<

bloodbaz

Posts: 3

Joined: Tue Dec 03, 2013 1:52 am

Post Sat Jan 25, 2014 5:43 pm

SPECTRA Advanced Graphics - Assembly

LCD has already posted up some great starter for 10 regarding ZXBC functions for the SPECTRA interface.
Most of my work is coded in Assembly (although I need to get around to some serious ZXBC programming soon) but we thought it would beuseful to share similar routines from an Assembly point of view.
I've put them under a separate, but similarly named thread - hope this is okay.

Firstly, a useful set of DEFINEs:
  Code:


; ----------------------------------------------------------------------
; Spectra
; ----------------------------------------------------------------------

; SPECTRA PORT ADDRESS
SPECTRA_PORT   .equ $7FDF   ; 32735

; SPECTRA PORT VALUES
SPECTRA_MODE_ROW   .equ 0
SPECTRA_MODE_QUAD   .equ 1   ; b0
SPECTRA_MODE_DUAL   .equ 2   ; b1
SPECTRA_MODE_SINGLE   .equ 3   ; b0+b1

SPECTRA_COL_BASIC   .equ 0
SPECTRA_COL_EXTRA   .equ 4   ; b2

SPECTRA_SINGLE_BYTE    .equ 0
SPECTRA_DOUBLE_BYTE    .equ 8   ; b3

SPECTRA_BORDER_STANDARD   .equ 0
SPECTRA_BORDER_ENHANCED   .equ 16   ; b4

SPECTRA_SCREEN_BANK_A   .equ 0
SPECTRA_SCREEN_BANK_B   .equ 32   ; b5

SPECTRA_SCREEN_0   .equ 0
SPECTRA_SCREEN_1   .equ 64   ; b6

SPECTRA_FULL_CELL   .equ 0
SPECTRA_HALF_CELL   .equ 128   ; b7

SPECTRA_COL_EXTRA_SINGLE .equ 4
SPECTRA_COL_EXTRA_DOUBLE .equ 12


Next a couple of Step Up/Step Down functions that accept an address in attribute memory and locates the corresponding address above or below.
Functions are "mode specific" (Row, Quad, Dual, Single or in newer terminology - Nx8, Nx4, Nx2, Nx1). Only Quad and Dual are provided here but I can post the others up later.
The Row version is identical to standard spectrum process and is simply adding or subtracting 32 bytes.
Single (not provided at present) is more complex due the screen having a hybrid of Nx1 and Nx2 in the top 2/3rds and bottom 1/3d screen respectively.
Anyway, here they are:

  Code:

; ------------------------------------------------------
; *AttrStepUp and *AttrStepDown
; Step Up and Down functions are a function of the mode
; only and half/full mode (b7) and single/double mode (b6)
; do not affect this values.  As such we have the following:
; variants:
;     RowAttrStepUp   RowAttrStepDown
; (imp)   QuadAttrStepUp   QuadAttrStepDown
; (imp)   DualAttrStepUp   DualAttrStepDown
;    SingleAttrStepUp SingleAttrStepDown
; Single is more complex because it changes resolution in the
; 3rd third.
; All StepUp/Down functions have HL as input and output
; and break A
; ------------------------------------------------------
   
; ------------------------------------------------------
; QuadAttrStepUp
; ------------------------------------------------------
QuadAttrStepUp:
   LD A,H
   DEC H
   AND 1   ; In a pixel step up with { L2 L1 L0 } we do an AND 7 here
   RET NZ
   ; Crossing a ROW
   LD A,L
   SUB 32
   LD L,A
   RET C
;   LD A,H
;   ADD A,2   ; In a pixel step up with { L2 L1 L0 } we do an ADD A,8 here
;   LD H,A   ; An ADD A, 2 is better handled with a couple of "DEC H" ops
   INC H
   INC H
   RET
   
; ------------------------------------------------------
; QuadAttrStepDown
; ------------------------------------------------------
QuadAttrStepDown:
   INC H
   LD A,H
   AND 1   ; In a pixel step down with { L2 L1 L0 } we do an AND 7 here
   RET NZ
   LD A,L
   ADD A,32
   LD L,A
   RET C
;   LD A,H
;   SUB 2   ; In a pixel step down with { L2 L1 L0 } we do an SUB 8 here
;   LD H,A   ; A SUB 2 is better handled with a couple of "DEC H" ops
   DEC H
   DEC H
   RET
   
   
; ------------------------------------------------------
; DualAttrStepUp
; ------------------------------------------------------
DualAttrStepUp:
   LD A,H
   DEC H
   AND 3   ; In a pixel step up with { L2 L1 L0 } we do an AND 7 here
   RET NZ
   ; Crossing a ROW
   LD A,L
   SUB 32
   LD L,A
   RET C
   LD A,H
   ADD A,4   ; In a pixel step up with { L2 L1 L0 } we do an ADD A,8 here
   LD H,A   ; An ADD A, 2 is better handled with a couple of "DEC H" ops
   RET
   
; ------------------------------------------------------
; DualAttrStepDown
; ------------------------------------------------------
DualAttrStepDown:
   INC H
   LD A,H
   AND 3   ; In a pixel step down with { L2 L1 L0 } we do an AND 3 here
   RET NZ
   LD A,L
   ADD A,32
   LD L,A
   RET C
   LD A,H
   SUB 4   ; In a pixel step down with { L2 L1 L0 } we do an SUB 8 here
   LD H,A
   RET



This is a SPECTRA test routine. It also tests for the (now defunct) v1 firmware which didn't support half-cell mode. Pretty much all SPECTRA boards will return "2".
You will notice that at the first block has conditional compilation (IFDEF SPECTRA_EMULATION) which I used when testing via an Emulator which doesn't support SPECTRA. It allowed me to still return that it does when it doesn't.
You can remove this initial block (up to the "ELSE") and the final "ENDIF" for the true Spectra Test implementation.

  Code:

; ------------------------------------------------------
; SpectraTest
; Tests for the presence of the SPECTRA interface
;
; Remarks
; To avoid any colour flash, perform a immediately before HALT before calling
; Tests for SPECTRA by OUTing, WAITing and then INing a series of bytes defined by SpectraTestBytes_v1
;
; Breaks:
;    BC (returns holding SPECTRA port)
;    HL (Spectra Not Found: Returns pointing to the byte that was tested for (written to the SPECTRA port))
;    A  (Spectra Not Found: Returns actual byte read from the SPECTRA port)
;
; Returns:
;    E: 0 = Not present; 1 = SPECTRA v1; 2 = SPECTRA v2
; ------------------------------------------------------

SpectraTest:
   IFDEF SPECTRA_EMULATION
   IF SPECTRA_EMULATION = "v1"
   LD E, 1
   ELSE
   LD E, 2
   ENDIF
   RET
   ELSE

   LD HL, SpectraTestBytes_v1
   LD BC, SPECTRA_PORT
   CALL .test
   LD E, 0
   RET NZ   ; Not Present (E=0)
   LD HL, SpectraTestBytes_v2
   INC E
   CALL .test
   JR NZ, .end
   INC E
   RET   ; SPECTRA v2
.end:   XOR A
   OUT (C), A
   RET

.test:   ; Write
   LD A, (HL)
   OUT (C), A
   
   ; Wait
   XOR A
.wait:   DEC A
   JR NZ, .wait
   
   ; Read
   IN A, (C)
   
   ; Test
   CP (HL)
   
   ; Fail: Return with Z Flag Reset
   RET NZ
   
   ; End of sequence (0)?
   OR A
   RET Z   ; Pass
   
   ; Test next byte
   INC HL
   JR .test

SpectraTestBytes_v1:
   ; 0 terminates the sequence but 0 is included in the test
   .defb SPECTRA_COL_EXTRA_SINGLE
   .defb SPECTRA_BORDER_ENHANCED
   .defb SPECTRA_SCREEN_BANK_B
   .defb 0
SpectraTestBytes_v2:
   .defb SPECTRA_HALF_CELL
   .defb 0
   ENDIF



I can post more up when I have time. Ciao!
<<

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Sun Sep 13, 2015 2:02 pm

Re: SPECTRA Advanced Graphics - Assembly

Thank you for your contribution. I'm currently very busy, but soon I will return to BorIDE and SPECTRA.
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!

Return to How-To & Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.

phpBB SEO