Интересно, никто не пробовал сделать текстовый режим для стандартного ROM бейсика. Грубо говоря - перехватить вывод символов и печатать не на экран спектрума а в текстовую консоль, скажем 80x25 символов. Насколько жизнеспособно?![]()
Интересно, никто не пробовал сделать текстовый режим для стандартного ROM бейсика. Грубо говоря - перехватить вывод символов и печатать не на экран спектрума а в текстовую консоль, скажем 80x25 символов. Насколько жизнеспособно?![]()
ZXMAK2 - Виртуальная Машина ZX Spectrum https://github.com/zxmak/ZXMAK2 (старая ссылка http://zxmak2.codeplex.com)
ZXMAK.NET - спектрум на C# http://sourceforge.net/projects/zxmak-dotnet
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
ну разве что для list и для новых прог, которые будут знать про увеличение ширины
в старых может некоординатный вывод перекосить, а для координатного смысла нет
Прихожу без разрешения, сею смерть и разрушение...
ZXMAK(16.04.2025)
Хм, попробовал - почему-то текст через пробелы отображается, т.е. символы укороченные,но занимают столько же места.
И при попытке ввести 10 PRINT "HELLO WORLD", почему-то сбросилось...
А исходник есть? Посмотреть - как подмена вывода производится?
Последний раз редактировалось ZXMAK; 16.04.2025 в 08:03.
ZXMAK2 - Виртуальная Машина ZX Spectrum https://github.com/zxmak/ZXMAK2 (старая ссылка http://zxmak2.codeplex.com)
ZXMAK.NET - спектрум на C# http://sourceforge.net/projects/zxmak-dotnet
Там командная строка печатается 32 символа в строке, а команды PRINT и LIST печатают 64 символа в строке.
Исходников конечно нет. Да и автор неизвестен.
Дык, это, там же есть нормальные «драйверы устройств», которые channels. Переопределить I/O нужного канала, да и всё. Так этот 64-х символьный вывод обычно и работает. А с вводом ещё проще. Их много есть, таких драйверов, и с исходниками и без. Ищется как «4x8 font driver». 32x22, прибитые гвоздями, это да, это практически, конечно, мешать будет. И область для редактирования (R, вроде) не упрощает особо.
С практической точки зрения, думаю, попробовать можно на любом эмуляторе – включить эмуляцию Interface 1 переназначить каналы K и S, для начала.
https://github.com/skx/lighthouse-of...master/prn.z80
ZXMAK2 - Виртуальная Машина ZX Spectrum https://github.com/zxmak/ZXMAK2 (старая ссылка http://zxmak2.codeplex.com)
ZXMAK.NET - спектрум на C# http://sourceforge.net/projects/zxmak-dotnet
поизучав немного ROM, нашел что адреса процедур для каналов хранятся в структуре адрес которой можно прочитать из ячейки CHANS=$5c4f.
Для обычного 48 бейсика структура обычно начинается с $5CB6. Структура содержит адрес процедуры вывода (2 байта), адрес процедуры ввода (2 байта) и 1 байт имя канала.
В ROM при инициализации эта область переносится LDIR-ом с адреса $15AF:
Тут канал 'S' - это верхняя основная область экрана, а канал 'K' - это нижние две строки, где поле ввода и редактирования.Код:; init-chan L15AF: DEFW L09F4 ; PRINT-OUT DEFW L10A8 ; KEY-INPUT DEFB $4B ; 'K' DEFW L09F4 ; PRINT-OUT DEFW L15C4 ; REPORT-J DEFB $53 ; 'S' DEFW L0F81 ; ADD-CHAR DEFW L15C4 ; REPORT-J DEFB $52 ; 'R' DEFW L09F4 ; PRINT-OUT DEFW L15C4 ; REPORT-J DEFB $50 ; 'P' DEFB $80 ; End Marker
Казалось бы замени процедуру PRINT-OUT для канала S на chan_4 и все должно работать, ан нет...
Пока бейсик программа работает - это срабатывает. Но как только останавливаешь по CS+BREAK, нажимаешь ENTER и тут PRINT-OUT адрес сам восстанавливается назад на ROM...
Непонятное поведение. Есть идеи как это обойти?
Вот код ROM который перетирает процедуры:
Любопытно, что код basic-64, который выше выложили, с родным 48 бейсиком работает и его каким-то образом перетирание не затрагивает, т.к. в ($5c51) лежит другая таблица. Пока не понятно за счет чего это достигается.Код:$0D99: ld hl,($5c51) ld de,$09f4 and a $0DA0: ld (hl),e inc hl ld (hl),d inc hl ld de,$10a8 ccf jr c,$0DA0
Вот код драйвера 4x8. После компиляции процедура chan_4 (т.е. PRINT-OUT для фонта 4x8) находится по адресу $c385. Запустив USR 50000 получаем установленный драйвер для канала #4. Для канала S можно руками в отладчике прописать по адресу $5cbb, но как написал выше - после останова программы значение перетирается на дефолтную процедуру $09F4:
Код:; --------------- ; 4x8 font driver, (c) 2007 Andrew Owen ; --------------- ; org 50000 #target ram #code TEST1, 50000, * ; -------------------------------- ; CREATE CHANNEL AND ATTACH STREAM ; -------------------------------- ; ; Based on code by Ian Beardsmore from Your Spectrum issue 7, September 1984. c_chan: ld hl,($5c53) ; a channel must be created below basic ; so look at the system variable PROG dec hl ; move hl down one address ld bc,$0005 ; the new channel takes 5 bytes call $1655 ; call the MAKE_ROOM routine inc hl ; move HL up one address ld bc,chan_4 ; could write the bytes directly but ; then code would be non-relocatable ld (hl),c ; low byte of the output routine inc hl ; move HL up one address push hl ; save this address for later ld (hl),b ; high byte of the output routine inc hl ; move HL up one address ld bc,$15c4 ; address of input routine ld (hl),c ; low byte of the input routine inc hl ; move HL up one address ld (hl),b ; high byte of the input routine inc hl ; move HL up one address ld (hl),'P' ; channel type; 'K', 'S', 'R' or 'P' ; attach stream pop hl ; the first address plus one of the ; extra space stored earlier ld de,($5c4f) ; store the contents of CHANS in DE and a ; clear the carry flag before ; calculation sbc hl,de ; the difference between the start of ; the channels area and the start of the ; extra space becomes the offset, stored ; in HL ex de,hl ; store the offset in DE ld hl,$5c10 ; store the contents of STRMS in HL ld a,$04 ; stream number 4 add a,$03 ; take account of streams -3 to -1 add a,a ; each of the seven default streams has ; two bytes of offset data ; the total number of bytes occupied, ; held in a, forms the offset for the ; new stream ld b,$00 ; set b to hold $00 ld c,a ; set the low byte of the offset add hl,bc ; the offset is added to the base ; address to give the correct location ; in the streams table to store the ; offset ld (hl),e ; the low byte of the offset inc hl ; move HL up one address ld (hl),d ; the high byte of the offset ret ; all done ;----------------------------------------------------------------------- ; ----------------- ; CHANNEL #4 OUTPUT ; ----------------- ; ; Based on code by Tony Samuels from Your Spectrum issue 13, April 1985. ; A channel wrapper for the 64-column display driver. chan_4: ld b,a ; save character ld a,(atflg) ; value of AT flag and a ; test against zero jr nz,getrow ; jump if not ld a,b ; restore character atchk: cp $16 ; test for AT jr nz,crchk ; if not test for CR ld a,$ff ; set the AT flag ld (atflg),a ; next character will be row ret ; return getrow: cp $fe ; test AT flag jr z,getcol ; jump if setting col ld a,b ; restore character cp $18 ; greater than 23? jr nc,err_b ; error if so ld (row),a ; store it in row ld hl,atflg ; AT flag dec (hl) ; indicates next character is col ret ; return getcol: ld a,b ; restore character cp $40 ; greater than 63? jr nc,err_b ; error if so ld (col),a ; store it in col xor a ; set a to zero ld (atflg),a ; store in AT flag ret ; return err_b: xor a ; set a to zero ld (atflg),a ; clear AT flag rst 08h ; defb $0a ; crchk: cp $0d ; check for return jr z,do_cr ; to carriage return if so call pr_64 ; print it ld hl,col ; increment inc (hl) ; the column ld a,(hl) ; cp $40 ; column 64? ret nz ; do_cr: xor a ; set A to zero ld (col),a ; reset column ld a,(row) ; get the row inc a ; increment it cp $18 ; row 24? jr z,wrap ; zend: ld (row),a ; write it back ret wrap: xor a ; jr zend ; ; ------------------------ ; 64 COLUMN DISPLAY DRIVER ; ------------------------ pr_64: rra ; divide by two with remainder in carry flag ld h,$00 ; clear H ld l,a ; CHAR to low byte of HL ex af,af' ; save the carry flag add hl,hl ; multiply add hl,hl ; by add hl,hl ; eight ld de,font-$80 ; offset to FONT add hl,de ; HL holds address of first byte of ; character map in FONT push hl ; save font address ; convert the row to the base screen address ld a,(row) ; get the row ld b,a ; save it and $18 ; mask off bit 3-4 ld d,a ; store high byte of offset in D ld a,b ; retrieve it and $07 ; mask off bit 0-2 rlca ; shift rlca ; five rlca ; bits rlca ; to the rlca ; left ld e,a ; store low byte of offset in E ; add the column ld a,(col) ; get the column rra ; divide by two with remainder in carry flag push af ; store the carry flag ld h,$40 ; base location ld l,a ; plus column offset add hl,de ; add the offset ex de,hl ; put the result back in DE ; HL now points to the location of the first byte of char data in FONT_1 ; DE points to the first screen byte in SCREEN_1 ; C holds the offset to the routine pop af ; restore column carry flag pop hl ; restore the font address jr nc,odd_col ; jump if odd column even_col: ex af,af' ; restore char position carry flag jr c,l_on_l ; left char on left col jr r_on_l ; right char on left col odd_col: ex af,af' ; restore char position carry flag jr nc,r_on_r ; right char on right col jr l_on_r ; left char on right col ; ------------------------------- ; WRITE A CHARACTER TO THE SCREEN ; ------------------------------- ; ; There are four separate routines ; HL points to the first byte of a character in FONT ; DE points to the first byte of the screen address ; left nibble on left hand side l_on_l: ld c,$08 ; 8 bytes to write ll_lp: ld a,(de) ; read byte at destination and $f0 ; mask area used by new character ld b,a ; store in b ld a,(hl) ; get byte of font and $0f ; mask off unused half or b ; combine with background ld (de),a ; write it back inc d ; point to next screen location inc hl ; point to next font data dec c ; adjust counter jr nz,ll_lp ; loop 8 times ret ; done ; right nibble on right hand side r_on_r: ld c,$08 ; 8 bytes to write rr_lp: ld a,(de) ; read byte at destination and $0f ; mask area used by new character ld b,a ; store in b ld a,(hl) ; get byte of font and $f0 ; mask off unused half or b ; combine with background ld (de),a ; write it back inc d ; point to next screen location inc hl ; point to next font data dec c ; adjust counter jr nz,rr_lp ; loop 8 times ret ; done ; left nibble on right hand side l_on_r: ld c,$08 ; 8 bytes to write lr_lp: ld a,(de) ; read byte at destination and $0f ; mask area used by new character ld b,a ; store in b ld a,(hl) ; get byte of font rrca ; shift right rrca ; four bits rrca ; leaving 7-4 rrca ; empty and $f0 ; or b ; combine with background ld (de),a ; write it back inc d ; point to next screen location inc hl ; point to next font data dec c ; adjust counter jr nz,lr_lp ; loop 8 times ret ; done ; right nibble on left hand side r_on_l: ld c,$08 ; 8 bytes to write rl_lp: ld a,(de) ; read byte at destination and $f0 ; mask area used by new character ld b,a ; store in b ld a,(hl) ; get byte of font rlca ; shift left rlca ; four bits rlca ; leaving 3-0 rlca ; empty and $0f ; or b ; combine with background ld (de),a ; write it back inc d ; point to next screen location inc hl ; point to next font data dec c ; adjust counter jr nz,rl_lp ; loop 8 times ret ; done ; -------------- ; TEXT VARIABLES ; -------------- ; ; Used by the 64 column driver atflg: defb $00 ; AT flag row: defb $00 ; row col: defb $00 ; col ; ------------------- ; half width 4x8 font ; ------------------- ; ; 384 bytes font: defb $00,$02,$02,$02,$02,$00,$02,$00,$00,$52,$57,$02,$02,$07,$02,$00; defb $00,$25,$71,$62,$32,$74,$25,$00,$00,$22,$42,$30,$50,$50,$30,$00; defb $00,$14,$22,$41,$41,$41,$22,$14,$00,$20,$70,$22,$57,$02,$00,$00; defb $00,$00,$00,$00,$07,$00,$20,$20,$00,$01,$01,$02,$02,$04,$14,$00; defb $00,$22,$56,$52,$52,$52,$27,$00,$00,$27,$51,$12,$21,$45,$72,$00; defb $00,$57,$54,$56,$71,$15,$12,$00,$00,$17,$21,$61,$52,$52,$22,$00; defb $00,$22,$55,$25,$53,$52,$24,$00,$00,$00,$00,$22,$00,$00,$22,$02; defb $00,$00,$10,$27,$40,$27,$10,$00,$00,$02,$45,$21,$12,$20,$42,$00; defb $00,$23,$55,$75,$77,$45,$35,$00,$00,$63,$54,$64,$54,$54,$63,$00; defb $00,$67,$54,$56,$54,$54,$67,$00,$00,$73,$44,$64,$45,$45,$43,$00; defb $00,$57,$52,$72,$52,$52,$57,$00,$00,$35,$15,$16,$55,$55,$25,$00; defb $00,$45,$47,$45,$45,$45,$75,$00,$00,$62,$55,$55,$55,$55,$52,$00; defb $00,$62,$55,$55,$65,$45,$43,$00,$00,$63,$54,$52,$61,$55,$52,$00; defb $00,$75,$25,$25,$25,$25,$22,$00,$00,$55,$55,$55,$55,$27,$25,$00; defb $00,$55,$55,$25,$22,$52,$52,$00,$00,$73,$12,$22,$22,$42,$72,$03; defb $00,$46,$42,$22,$22,$12,$12,$06,$00,$20,$50,$00,$00,$00,$00,$0F; defb $00,$20,$10,$03,$05,$05,$03,$00,$00,$40,$40,$63,$54,$54,$63,$00; defb $00,$10,$10,$32,$55,$56,$33,$00,$00,$10,$20,$73,$25,$25,$43,$06; defb $00,$42,$40,$66,$52,$52,$57,$00,$00,$14,$04,$35,$16,$15,$55,$20; defb $00,$60,$20,$25,$27,$25,$75,$00,$00,$00,$00,$62,$55,$55,$52,$00; defb $00,$00,$00,$63,$55,$55,$63,$41,$00,$00,$00,$53,$66,$43,$46,$00; defb $00,$00,$20,$75,$25,$25,$12,$00,$00,$00,$00,$55,$55,$27,$25,$00; defb $00,$00,$00,$55,$25,$25,$53,$06,$00,$01,$02,$72,$34,$62,$72,$01; defb $00,$24,$22,$22,$21,$22,$22,$04,$00,$56,$A9,$06,$04,$06,$09,$06;
Последний раз редактировалось ZXMAK; 16.04.2025 в 22:56.
ZXMAK2 - Виртуальная Машина ZX Spectrum https://github.com/zxmak/ZXMAK2 (старая ссылка http://zxmak2.codeplex.com)
ZXMAK.NET - спектрум на C# http://sourceforge.net/projects/zxmak-dotnet
Я изучал работу каналов и потоков по книге "ZX Spectrum для пользователей и программистов".
ZXMAK(17.04.2025)
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)