Page 1 of 1
Problem with ts_vmod()
Posted: Sun Feb 11, 2018 3:19 pm
by Stefan123
I have a problem with ts_vmod() in zxn.h. When I use the following line, I can verify in the ZEsarUX debugger that the 0xFF port is to 0x06 but not 0x3E as you would have expected:
However, the following workaround works as expected:
Code: Select all
z80_outp(0xFF, IO_TVM_HIRES_WHITE);
Posted: Mon Feb 12, 2018 6:06 am
by alvin
Stefan123 wrote:I have a problem with ts_vmod() in zxn.h. When I use the following line, I can verify in the ZEsarUX debugger that the 0xFF port is to 0x06 but not 0x3E as you would have expected:
ts_vmod is intended to take a paper colour in its argument:
ts_vmod(TVM_HIRES | PAPER_WHITE);
Code: Select all
// timex video mode
#define TVM_SPECTRUM __IO_TVM_DFILE_1 // 256x192 pix, 32x24 attr
#define TVM_HICOLOR __IO_TVM_HICOLOR // 256x192 pix, 32x192 attr
#define TVM_HIRES __IO_TVM_HIRES // 512x192 pix or with paper colour
extern void ts_vmod(unsigned char mode) __preserves_regs(b,c,d,e,iyl,iyh);
extern void ts_vmod_fastcall(unsigned char mode) __preserves_regs(b,c,d,e,iyl,iyh) __z88dk_fastcall;
#define ts_vmod(a) ts_vmod_fastcall(a)
The reason is port 0xff specifies colour in bits 3..5 which is the same location as paper colours in attribute bytes so it's possible to use the already existing macros PAPER_*. ts_vmod will invert bits 3..5 to turn the paper colour into an ink colour before mixing that with the bits in port 0xff that have to be preserved.
Code: Select all
asm_ts_vmod:
; change video mode
;
; enter : l = mode
;
; uses : af, l
ld a,l
xor $38
and $3f
ld l,a
in a,($ff)
and $c0
or l
out ($ff),a
ret
Posted: Mon Feb 12, 2018 6:09 am
by alvin
It saves the definition of yet another set of colour macros. Setting ts_vmod is not going to be a timing sensitive thing in most applications and if it is, you'd most likely want to avoid the function call anyway and set port 0xff directly with "IO_FF = ...;"
Posted: Mon Feb 12, 2018 5:44 pm
by Stefan123
I thought the IO_TVM_HIRES_BLACK, IO_TVM_HIRES_BLUE, ..., IO_TVM_HIRES_WHITE macros in zxn.h were supposed to be used as arguments to ts_vmod().
Posted: Tue Feb 13, 2018 12:30 am
by alvin
Stefan123 wrote:I thought the IO_TVM_HIRES_BLACK, IO_TVM_HIRES_BLUE, ..., IO_TVM_HIRES_WHITE macros in zxn.h were supposed to be used as arguments to ts_vmod().
I forgot those were there. Anything with IO in front has to do with io ports:
https://github.com/z88dk/z88dk/blob/mas ... zxn.h#L118
https://github.com/z88dk/z88dk/blob/mas ... zxn.h#L191
Each io port is given two names: IO_{PORT_NUM} and IO_{TEXT_NAME} so foe port 0xff they are:
Code: Select all
__sfr __at 0xff IO_FF;
__sfr __at __IO_TIMEX_VIDEO_MODE IO_TIMEX_VIDEO_MODE;
And then defined bits for the port are given names IO_{PORT_NAME_INITIAL}_BITNAME
Code: Select all
// 0xff, IO_TIMEX_VIDEO_MODE
#define IO_TVM_DISABLE_ULA_INTERRUPT __IO_TVM_DISABLE_ULA_INTERRUPT
#define IO_TVM_DFILE_1 __IO_TVM_DFILE_1
#define IO_TVM_DFILE_2 __IO_TVM_DFILE_2
#define IO_TVM_HICOLOR __IO_TVM_HICOLOR
#define IO_TVM_HIRES __IO_TVM_HIRES
#define IO_TVM_HIRES_BLACK __IO_TVM_HIRES_BLACK
#define IO_TVM_HIRES_BLUE __IO_TVM_HIRES_BLUE
#define IO_TVM_HIRES_RED __IO_TVM_HIRES_RED
#define IO_TVM_HIRES_MAGENTA __IO_TVM_HIRES_MAGENTA
#define IO_TVM_HIRES_GREEN __IO_TVM_HIRES_GREEN
#define IO_TVM_HIRES_CYAN __IO_TVM_HIRES_CYAN
#define IO_TVM_HIRES_YELLOW __IO_TVM_HIRES_YELLOW
#define IO_TVM_HIRES_WHITE __IO_TVM_HIRES_WHITE
And the port initial in this case is "TVM" which also happens to be the initial for the function "ts_vmod()" so that its flag bits also have a TVM initial in their names:
Code: Select all
// timex video mode
#define TVM_SPECTRUM __IO_TVM_DFILE_1 // 256x192 pix, 32x24 attr
#define TVM_HICOLOR __IO_TVM_HICOLOR // 256x192 pix, 32x192 attr
#define TVM_HIRES __IO_TVM_HIRES // 512x192 pix or with paper colour
extern void ts_vmod(unsigned char mode) __preserves_regs(b,c,d,e,iyl,iyh);
extern void ts_vmod_fastcall(unsigned char mode) __preserves_regs(b,c,d,e,iyl,iyh) __z88dk_fastcall;
#define ts_vmod(a) ts_vmod_fastcall(a)
So I can see the confusion. I'm not entirely sure if it's a good thing to name io ports rather than just sticking to port numbers in the name but it's used in the sms target for vdp address and data because that may help in the portability of libraries for TMS98xx chips.
Maybe this last set of constants should be renamed with initial TSVM to avoid confusion:
Code: Select all
// timex video mode
#define TSVM_SPECTRUM __IO_TVM_DFILE_1 // 256x192 pix, 32x24 attr
#define TSVM_HICOLOR __IO_TVM_HICOLOR // 256x192 pix, 32x192 attr
#define TSVM_HIRES __IO_TVM_HIRES // 512x192 pix or with paper colour
Would that help?
Posted: Tue Feb 13, 2018 12:35 am
by alvin
Maybe we should have the bit names also available with port number in them:
Code: Select all
#define IO_FF_DISABLE_ULA_INTERRUPT __IO_TVM_DISABLE_ULA_INTERRUPT
#define IO_FF_DFILE_1 __IO_TVM_DFILE_1
#define IO_FF_DFILE_2 __IO_TVM_DFILE_2
#define IO_FF_HICOLOR __IO_TVM_HICOLOR
#define IO_FF_HIRES __IO_TVM_HIRES
#define IO_FF_HIRES_BLACK __IO_TVM_HIRES_BLACK
#define IO_FF_HIRES_BLUE __IO_TVM_HIRES_BLUE
#define IO_FF_HIRES_RED __IO_TVM_HIRES_RED
#define IO_FF_HIRES_MAGENTA __IO_TVM_HIRES_MAGENTA
#define IO_FF_HIRES_GREEN __IO_TVM_HIRES_GREEN
#define IO_FF_HIRES_CYAN __IO_TVM_HIRES_CYAN
#define IO_FF_HIRES_YELLOW __IO_TVM_HIRES_YELLOW
#define IO_FF_HIRES_WHITE __IO_TVM_HIRES_WHITE
Posted: Tue Feb 13, 2018 8:11 pm
by Stefan123
Naming is not easy... Maybe just adding comments above the IO_TVM_HIRES_BLACK macro group and TVM_HIRES macro group explaining their purpose would help? It would have helped me