Commit e87eeeca authored by Ben Avison's avatar Ben Avison
Browse files

Added compile-time support for full-resolution teletext characters in teletext...

Added compile-time support for full-resolution teletext characters in teletext emulation mode (MODE 7) for that authentic BBC Micro feel.

  Also introduced a few useful teletext control features via VDU 23,18.
  Unrelatedly, fixed *ScreenLoad to work for interlaced displays.

Detail:
  The new typeface is designed on a 16x20 grid (previously we had used 8x10),
  so it uses a screen resolution of 640x500 pixels (rather than 320x250).
  Since we have been unable to source a genuine teletext font, and since
  examination of a BBC Micro suggests that the genuine font may not have been
  a power-of-2 pixels wide, I have designed one specially, based upon the one
  supplied in Zap distributions (a 12x20 font). Rather than increase the
  amount of workspace that the kernel requires for cacheing graphic
  characters, it now generates them on the fly, as they are required; this
  should only add about 25% to their rendering time.

  The new VDU 23 sequences are as follows:

  VDU 23,18,0,mode,0,0,0,0,0,0
    Switch transparency mode
      mode = 0: "Text" mode: the whole display is set opaque
      mode = 1: "Mix" mode: foreground colours, and both foreground and
        background of boxed text are opaque; non-boxed background colours are
        all transparent
      mode = 2: "Box" mode: boxed regions are opaque, others are transparent
      mode = 3: "TV" mode: the whole display is set transparent
    Default is mode = 0.

  VDU 23,18,1,suspend,0,0,0,0,0,0
    Suspend or resume bitmap updates
    This call allows an application to request that the kernel suspends
    updates to the framebuffer bitmap. This allows for a significant speed
    increase in the rendering time for a large amount of text, for example
    when redrawing a complete teletext page, because each time you plot a
    single character, it can cause the whole of the rest of the line to be
    re-rendered. When you switch out of suspend mode, the whole screen is
    refreshed in a single pass. Note that the appearance of the display is
    undefined is you cause a hardware scroll while in suspend mode.
      suspend = 0: screen update is enabled
      suspend = 1: screen update is suspended
    Default is suspend = 0.

  VDU 23,18,2,reveal,0,0,0,0,0,0
    Reveal/conceal
      reveal = 0: characters between the Conceal control code and the next
        colour control code are replaced by spaces
      reveal = 1: all characters are displayed
    Default is reveal = 0.

  VDU 23,18,3,black_emable,0,0,0,0,0,0
    Enable/disable black foreground colour control codes
      black_enable = 0: control codes &80 and &90 do nothing
      black_enable = 1: control code &80 selects black text, control code
        &90 selects black graphics
    Default is black_enable = 0.

  I have performed some timing tests on the rendering of complete teletext
  pages grabbed from the teletext server. These show that the new code
  generally imposes a 2x speed hit. However, when using the VDU 23,18,1
  suspend function, this improves to a 20% speed increase when compared to
  the old low-resolution code. Better still, because the framebuffer is only
  being updated for the final stage of this process, the screen *appears* to
  be updated some 3x faster than with the old code!

  A comment on the VDU variable Log2BPC is in order: in previous kernels,
  this was able unambiguously to refer to both the framebuffer width of a
  character in bytes, and the framebuffer width of an "addressable pixel" in
  bits; this no longer works with the 16-pixel wide teletext font. Bearing
  in mind that future kernels may support Unicode system fonts where the
  width varies from character to character, I have chosen to fix Log2BPC to
  the "addressable pixel" definition.

Admin:
  Requires HdrSrc 0.89 and (for non-desktop builds) Interlace 0.61. A monitor
  definition file containing a definition for a 640x500 screen mode is also
  required; version 0.40 of ModeFiles contains a suitable mode for STB-400.

  Tested fairly rigourously on an Ursula build, a Lazarus build and an
  STB-400 build, using genuine teletext pages and Yellow River Kingdom.

Version 5.30. Tagged as 'Kernel-5_30'
parent 3e4ce193
The new typeface is designed on a 16x20 grid (previously we had used 8x10),
so it uses a screen resolution of 640x500 pixels (rather than 320x250).
Since we have been unable to source a genuine teletext font, and since
examination of a BBC Micro suggests that the genuine font may not have been
a power-of-2 pixels wide, I have designed one specially, based upon the one
supplied in Zap distributions (a 12x20 font). Rather than increase the
amount of workspace that the kernel requires for cacheing graphic
characters, it now generates them on the fly, as they are required; this
should only add about 25% to their rendering time.
The new VDU 23 sequences are as follows:
VDU 23,18,0,mode,0,0,0,0,0,0
Switch transparency mode
mode = 0: "Text" mode: the whole display is set opaque
mode = 1: "Mix" mode: foreground colours, and both foreground and
background of boxed text are opaque; non-boxed background colours are
all transparent
mode = 2: "Box" mode: boxed regions are opaque, others are transparent
mode = 3: "TV" mode: the whole display is set transparent
Default is mode = 0.
VDU 23,18,1,suspend,0,0,0,0,0,0
Suspend or resume bitmap updates
This call allows an application to request that the kernel suspends
updates to the framebuffer bitmap. This allows for a significant speed
increase in the rendering time for a large amount of text, for example
when redrawing a complete teletext page, because each time you plot a
single character, it can cause the whole of the rest of the line to be
re-rendered. When you switch out of suspend mode, the whole screen is
refreshed in a single pass. Note that the appearance of the display is
undefined is you cause a hardware scroll while in suspend mode.
suspend = 0: screen update is enabled
suspend = 1: screen update is suspended
Default is suspend = 0.
VDU 23,18,2,reveal,0,0,0,0,0,0
Reveal/conceal
reveal = 0: characters between the Conceal control code and the next
colour control code are replaced by spaces
reveal = 1: all characters are displayed
Default is reveal = 0.
VDU 23,18,3,black_emable,0,0,0,0,0,0
Enable/disable black foreground colour control codes
black_enable = 0: control codes &80 and &90 do nothing
black_enable = 1: control code &80 selects black text, control code
&90 selects black graphics
Default is black_enable = 0.
I have performed some timing tests on the rendering of complete teletext
pages grabbed from the teletext server. These show that the new code
generally imposes a 2x speed hit. However, when using the VDU 23,18,1
suspend function, this improves to a 20% speed increase when compared to
the old low-resolution code. Better still, because the framebuffer is only
being updated for the final stage of this process, the screen *appears* to
be updated some 3x faster than with the old code!
A comment on the VDU variable Log2BPC is in order: in previous kernels,
this was able unambiguously to refer to both the framebuffer width of a
character in bytes, and the framebuffer width of an "addressable pixel" in
bits; this no longer works with the 16-pixel wide teletext font. Bearing
in mind that future kernels may support Unicode system fonts where the
width varies from character to character, I have chosen to fix Log2BPC to
the "addressable pixel" definition.
......@@ -8,11 +8,11 @@
GBLS Module_FullVersion
GBLS Module_ApplicationDate2
GBLS Module_ApplicationDate4
Module_MajorVersion SETS "5.29"
Module_Version SETA 529
Module_MajorVersion SETS "5.30"
Module_Version SETA 530
Module_MinorVersion SETS ""
Module_Date SETS "27 Jun 2000"
Module_ApplicationDate2 SETS "27-Jun-00"
Module_ApplicationDate4 SETS "27-Jun-2000"
Module_FullVersion SETS "5.29"
Module_Date SETS "28 Jun 2000"
Module_ApplicationDate2 SETS "28-Jun-00"
Module_ApplicationDate4 SETS "28-Jun-2000"
Module_FullVersion SETS "5.30"
END
/* (5.29)
/* (5.30)
*
* This file is automatically maintained by srccommit, do not edit manually.
*
*/
#define Module_MajorVersion_CMHG 5.29
#define Module_MajorVersion_CMHG 5.30
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 27 Jun 2000
#define Module_Date_CMHG 28 Jun 2000
#define Module_MajorVersion "5.29"
#define Module_Version 529
#define Module_MajorVersion "5.30"
#define Module_Version 530
#define Module_MinorVersion ""
#define Module_Date "27 Jun 2000"
#define Module_Date "28 Jun 2000"
#define Module_ApplicationDate2 "27-Jun-00"
#define Module_ApplicationDate4 "27-Jun-2000"
#define Module_ApplicationDate2 "28-Jun-00"
#define Module_ApplicationDate4 "28-Jun-2000"
#define Module_FullVersion "5.29"
#define Module_FullVersion "5.30"
......@@ -537,7 +537,7 @@ AspectRatio # 4 ; Pixel shape : 0 square, 1 horz rect, 2 vert rect
BitsPerPix # 4 ; Bits per pixel (1,2,4,8)
BytesPerChar # 4 ; Bytes per one line of character
BytesPerChar # 4 ; Bytes per 8 pixels of character
; (same as BitsPerPix except in double pixel modes)
CursorFudgeFactor # 4 ; Factor for horizontal cursor positioning
......@@ -773,6 +773,25 @@ TeletextCount # 4 ; Number of vsyncs till next teletext flash
WrchNbit # 4 ; Pointer to char code for current mode
[ HiResTTX
CharWidth # 4 ; Width of a character in bytes (same as BytesPerChar except
; in MODE 7, where characters are 16 pixels wide)
]
TTXFlags # 4 ; VDU 23,18 flags
TTXFlag_Suspend * 1:SHL:0
TTXFlag_Conceal * 1:SHL:1
TTXFlag_BlackEnable * 1:SHL:2
TTXFlag_TransModeShift * 3
TTXFlag_TransModeMask * 3:SHL:TTXFlag_TransModeShift
; bits 9-11 must be zero
TTXFlag_FgTransEOR * 1:SHL:12
; bits 13-15 must be zero
TTXFlag_BgTransEOR * 1:SHL:16
; bits 17-19 must be zero
TTXFlag_FgTransBIC * 1:SHL:20
; bits 21-23 must be zero
TTXFlag_BgTransBIC * 1:SHL:24
BeepBlock # 8 ; OSWORD block for VDU 7
ScreenMemoryClaimed # 1 ; NZ => memory has been claimed or is unusable
......
......@@ -749,7 +749,11 @@ MoveRight
CMP R0, R4
MOVCS PC, R14
LDR R2, [R11, #CursorAddr-CursorX]
[ HiResTTX
LDR R3, [WsPtr, #CharWidth]
|
LDR R3, [WsPtr, #BytesPerChar]
]
ADD R0, R0, #1
ADD R2, R2, R3
STR R0, [R11, #CursorX-CursorX]
......@@ -764,7 +768,11 @@ MoveLeft
CMP R4, R0
MOVCS PC, R14
LDR R2, [R11, #CursorAddr-CursorX]
[ HiResTTX
LDR R3, [WsPtr, #CharWidth]
|
LDR R3, [WsPtr, #BytesPerChar]
]
SUB R0, R0, #1
SUB R2, R2, R3
STR R0, [R11, #CursorX-CursorX]
......@@ -836,7 +844,11 @@ CHT
LDR R0, [WsPtr, #CursorX]
LDR R2, [WsPtr, #CursorAddr]
[ HiResTTX
LDR R3, [WsPtr, #CharWidth]
|
LDR R3, [WsPtr, #BytesPerChar]
]
LDR R4, [WsPtr, #TWRCol]
ADD R0, R0, #1
......
......@@ -176,6 +176,14 @@ Cursor2loop
MOV PC, R14
CursorTeletext
[ HiResTTX
Push "R0, R1, R14"
ADD R0, R0, #160*1024 ; go to other screen
ADD R1, R1, #160*1024
BL Cursor8bit
Pull "R0, R1, R14"
B Cursor8bit
|
Push "R0, R1, R14"
ADD R0, R0, #40*1024 ; go to other screen
ADD R1, R1, #40*1024
......@@ -183,6 +191,7 @@ CursorTeletext
Pull "R0, R1, R14"
; and drop thru to ...
]
Cursor4bit
LDR R8, [R0, R2]!
......@@ -350,7 +359,11 @@ TeletextFlashTest ROUT
BNE %FT20 ; count not expired
LDR R1, [WsPtr, #TeletextOffset]
[ HiResTTX
EORS R1, R1, #160*1024 ; switch to other flash bank
|
EORS R1, R1, #40*1024 ; switch to other flash bank
]
STR R1, [WsPtr, #TeletextOffset]
MOVEQ R3, #OnFlashTime
MOVNE R3, #OffFlashTime
......@@ -622,7 +635,11 @@ AddressCursors
InputCursorLeft
LDR R0, [WsPtr, #InputCursorX]
LDR R2, [WsPtr, #InputCursorAddr]
[ HiResTTX
LDR R3, [WsPtr, #CharWidth]
|
LDR R3, [WsPtr, #BytesPerChar]
]
LDR R4, [WsPtr, #TWLCol]
SUB R0, R0, #1
......@@ -639,7 +656,11 @@ InputCursorLeft
InputCursorRight
LDR R0, [WsPtr, #InputCursorX]
LDR R2, [WsPtr, #InputCursorAddr]
[ HiResTTX
LDR R3, [WsPtr, #CharWidth]
|
LDR R3, [WsPtr, #BytesPerChar]
]
LDR R4, [WsPtr, #TWRCol]
ADD R0, R0, #1
......
......@@ -2669,7 +2669,7 @@ ETBtab
; NB All other labels for Vdu23 are in TMD files so I don't have to pester RCM
Vdu23_18
;Vdu23_18 ; Assigned to Teletext operations
Vdu23_19
Vdu23_20
Vdu23_21
......
......@@ -261,6 +261,15 @@ ScreenLoad ROUT
TEQ R0, R5 ; and spritewidth=full screen
BNE %FT05
[ {TRUE}
LDR R14, [WsPtr, #Log2BPC]
MOV R1, R5, LSL R14 ; bit size of 1 row of pixels
MOV R1, R1, LSR #3 ; byte size of 1 row of pixels
LDR R14, [WsPtr, #LineLength] ; LineLength (in bytes)
TEQ R1, R14 ; if they differ (eg interlaced mode)
BNE %FT05 ; then we can't optimise
]
; we know we can do it all in one chunk
; work out screen address and sprite offset
......
......@@ -263,6 +263,12 @@ SwitchOutputToMask ROUT
MOV R7, R8, LSL R1 ; bpc = 1 << lbpc
STR R7, [WsPtr, #BytesPerChar]
[ HiResTTX
TST R6, #Flag_Teletext ; in teletext mode
MOVNE R7, R7, LSL #1 ; characters are 16 pixels
STR R7, [WsPtr, #CharWidth]
]
TST R6, #Flag_BBCGapMode ; is it a BBC gap mode ?
MOVNE R7, #&55 ; yes, then use colour 1
BNE %FT70
......@@ -283,6 +289,10 @@ SwitchOutputToMask ROUT
STR R7, [WsPtr, #RowMult]
STR R7, [WsPtr, #TCharSpaceY]
MOV R8, #8
[ HiResTTX
TST R6, #Flag_Teletext
MOVNE R8, #16
]
STR R8, [WsPtr, #TCharSizeX]
STR R8, [WsPtr, #TCharSpaceX]
......
......@@ -327,7 +327,11 @@ BigVIDCTable
& VLN_4 - BigVIDCTable ; 4
& VLN_5 - BigVIDCTable ; 5
& VLN_6 - BigVIDCTable ; 6
[ HiResTTX
& -1 ; 7
|
& VLN_7 - BigVIDCTable ; 7
]
& VLN_8 - BigVIDCTable ; 8
& VLN_9 - BigVIDCTable ; 9
& VLN_10 - BigVIDCTable ; 10
......@@ -812,7 +816,9 @@ VLN_3 VIDC_List 1, 76, 88, 96, 640, 96, 28, 3,19,19,250,19, 2,16000,0
VLN_4 VIDC_List 0, 76, 88, 96, 640, 96, 28, 3,19,16,256,16, 2,16000,0 ; MODE 4
VLN_5 VIDC_List 1, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 5
VLN_6 VIDC_List 1, 38, 44, 48, 320, 48, 14, 3,19,19,250,19, 2, 8000,0 ; MODE 6
[ :LNOT: HiResTTX
VLN_7 VIDC_List 2, 38, 44, 48, 320, 48, 14, 3,19,19,250,19, 2, 8000,0 ; MODE 7
]
VLN_8 VIDC_List 1, 76, 88, 96, 640, 96, 28, 3,19,16,256,16, 2,16000,0 ; MODE 8
VLN_9 VIDC_List 2, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 9
VLN_10 VIDC_List 3, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 10
......@@ -837,7 +843,11 @@ VLM_3 VIDC_List 1, 72, 62, 88, 640, 88, 74, 3,16,20,250,20, 3,16000,0
VLM_4 VIDC_List 0, 72, 62, 88, 640, 88, 74, 3,16,17,256,17, 3,16000,0 ; MODE 4
VLM_5 VIDC_List 1, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 5
VLM_6 VIDC_List 1, 36, 30, 44, 320, 44, 38, 3,16,20,250,20, 3, 8000,0 ; MODE 6
[ HiResTTX
VLM_7 VIDC_List 2, 56,112, 0, 640, 0, 88, 3,18, 6,500, 6, 1,24000,0 ; MODE 7
|
VLM_7 VIDC_List 2, 36, 30, 44, 320, 44, 38, 3,16,20,250,20, 3, 8000,0 ; MODE 7
]
VLM_8 VIDC_List 1, 72, 62, 88, 640, 88, 74, 3,16,17,256,17, 3,16000,0 ; MODE 8
VLM_9 VIDC_List 2, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 9
VLM_10 VIDC_List 3, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 10
......@@ -929,7 +939,11 @@ F_VLM_32 * 0
]
FrameRateTable
[ HiResTTX
= F_VLN_0, F_VLN_1, F_VLN_2, F_VLN_3, F_VLN_4, F_VLN_5, F_VLN_6, F_VLM_7
|
= F_VLN_0, F_VLN_1, F_VLN_2, F_VLN_3, F_VLN_4, F_VLN_5, F_VLN_6, F_VLN_7
]
= F_VLN_8, F_VLN_9, F_VLN_10, F_VLN_11, F_VLN_12, F_VLN_13, F_VLN_14, F_VLN_15
= F_VLN_16, F_VLN_17, F_VLM_18, F_VLM_19, F_VLM_20, F_VLM_21, F_VLN_22, F_VLH_23
= F_VLN_24, F_VLM_25, F_VLM_26, F_VLM_27, F_VLM_28, F_VLM_29, F_VLM_30, F_VLM_31
......@@ -1150,7 +1164,11 @@ VW_3 VWSTAB 3, 40K,160, 639,249,5,1,2, 1, 79, 24,1,1,0,0,Flag_NonGraphic+Fla
VW_4 VWSTAB 4, 20K, 80, 319,255,4,2,2, 1, 39, 31,1,0,0,4,0 ; MODE 4
VW_5 VWSTAB 5, 20K, 80, 159,255,4,3,2, 3, 19, 31,2,1,1,2,0 ; MODE 5
VW_6 VWSTAB 6, 20K, 80, 319,249,4,2,2, 1, 39, 24,1,1,0,0,Flag_NonGraphic+Flag_GapMode+Flag_BBCGapMode ; MODE 6
[ HiResTTX
VW_7 VWSTAB 7,320K,320, 639,499,5,1,1,15, 39, 24,2,2,4,0,Flag_NonGraphic+Flag_GapMode+Flag_Teletext+Flag_DoubleVertical ; MODE 7
|
VW_7 VWSTAB 7, 80K,160, 319,249,5,2,2,15, 39, 24,2,2,4,0,Flag_NonGraphic+Flag_GapMode+Flag_Teletext ; MODE 7
]
VW_8 VWSTAB 8, 40K,160, 639,255,5,1,2, 3, 79, 31,1,1,1,2,0 ; MODE 8
VW_9 VWSTAB 9, 40K,160, 319,255,5,2,2,15, 39, 31,2,2,2,3,0 ; MODE 9
VW_10 VWSTAB 10, 80K,320, 159,255,6,3,2,63, 19, 31,4,3,3,5,0 ; MODE 10
......
This diff is collapsed.
......@@ -423,6 +423,11 @@ AddressCursor
AddressR0R1 ROUT
LDR R4, [WsPtr, #RowLength]
LDR R3, [WsPtr, #Log2BPC]
[ HiResTTX
LDR R2, [WsPtr, #ModeFlags]
TST R2, #Flag_Teletext
ADDNE R3, R3, #1
]
LDR R2, [WsPtr, #ScreenStart] ; start address of top of screen
ADD R2, R2, R0, LSL R3 ; add in X offset
MLA R2, R4, R1, R2 ; add in Y*RowLength
......@@ -849,7 +854,9 @@ Wrch4bit
AND R0, R0, #(Flag_GapMode :OR: Flag_BBCGapMode) ; we want R0=0 iff
EOR R0, R0, #Flag_GapMode ; (gapmode AND NOT bbcgapmode)
MOV mask, #&FF000000 ; don't set mask in Wrch4bitTTX
[ :LNOT: HiResTTX
Wrch4bitTTX
]
AND byte, mask, tophalf, LSL #24
LDR scrbyte, [bigfont, byte, LSR #22]
STR scrbyte, [screen], linelen
......@@ -1109,7 +1116,11 @@ BS
LDR R0, [WsPtr, #CursorX]
LDR R2, [WsPtr, #CursorAddr]
[ HiResTTX
LDR R3, [WsPtr, #CharWidth]
|
LDR R3, [WsPtr, #BytesPerChar]
]
LDR R4, [WsPtr, #TWLCol]
SUB R0, R0, #1 ; no Master wazerks yet !
......@@ -1151,7 +1162,11 @@ HT
LDR R0, [WsPtr, #CursorX]
LDR R2, [WsPtr, #CursorAddr]
[ HiResTTX
LDR R3, [WsPtr, #CharWidth]
|
LDR R3, [WsPtr, #BytesPerChar]
]
LDR R4, [WsPtr, #TWRCol]
ADD R0, R0, #1
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment