Научно-технический кооператив "Спрайт" г. Новосибирск 1992 ОПЕРАЦИОННАЯ СИСТЕМА "С П Р А Й Т" (версия 1.3) РУКОВОДСТВО СИСТЕМНОГО ПРОГРАММИСТА I.3. Блок системных программ ввода-вывода IOSUB Руководство по IOSUB разрабатывается. В качестве пред- варительного описания поставляется исходный текст модуля. ; IOSUB.ASM 13.02.92 ; ; БАЗОВЫЙ КОМПЛЕКТ ПОДПРОГРАММ ; НИЖНЕГО УРОВНЯ ДЛЯ УПРАВЛЕНИЯ ; ВВОДОМ-ВЫВОДОМ, ПАМЯТЬЮ, ; ПРЕРЫВАНИЯМИ ; ; (C)1992 НТК "Спрайт", В.А.Цикоза ORG $300-$18 (8*число внешних вызовов) SBTL 'ОПРЕДЕЛЕНИЯ АППАРАТНЫХ КОНСТАНТ' A7 EQU ?7 Объектная машина A9 EQU ?9 BIT3 EQU $2C код команды BIT Abs ; Ячейки внутреннего интерфейса: KBD EQU $C000 регистр данных клавиатуры KBDSTRB EQU $C010 PL/MI - не/готовность KBD KBDREG EQU $C063 PL/MI - РУС/LAT SPEAKR EQU $C030 динамик IRPT1 EQU $C040 вкл.прерывания IF A7 IRPT2 EQU $C050 выкл.прерывания ELSE A9 IRPT2 EQU $C020 ENDIF BTNREG EQU $C061 +0/1 кнопка потенциометра PDLREG EQU $C064 +0/1 ручка потенциометра PDLTRIG EQU $C070 сброс потенциометра DISPLAY EQU $C700 +XX выбор режима экрана ; Выбор состояний памяти: STA CX00+ IF A7 DBLB EQU 0 OZU1 EQU 8 банки доп.OЗУ OZU2 EQU 9 PZU1 EQU $A0 чтение ПЗУ PZU2 EQU $A1 PZUWR EQU $20 EOR PZUхх: запись DBANK EQU $40 ELSE A9 DBLB EQU $80 бит двойного банка OZU1 EQU $44 ,55 дв.банки доп.OЗУ OZU2 EQU $4C ,5D PZU1 EQU $66 ,77 дв.банки ПЗУ PZU2 EQU $6E ,7F ENDIF ; Кодировка цветов в экр.памяти (INVFLG): REDCLR EQU 1 GRNCLR EQU 2 YELCLR EQU 3 BLUCLR EQU 4 VIOCLR EQU 5 NAVCLR EQU 6 WHTCLR EQU 7 NORMLB EQU $28 INVERB EQU $00 FLASHB EQU $08 ; Спец.символы, принятые в IOSUB ; для управления вводом-выводом: ; - вывод: NORMSYM EQU $81 ^A/0 нормальный фон INVSYM EQU $82 ^B/ф. инверсный FLSHSYM EQU $83 ^C/ф= мерцающий BELLSYM EQU $87 ^G звонок LEFTSYM EQU $88 ^H/<- влево курсор HOMESYM EQU $8B ^K курсор в начало экрана CLSSYM EQU $8C ^L очистка экрана RETSYM EQU $8D ^M/ПC перевод строки CLINSYM EQU $8F ^O очистка тек.строки REDSYM EQU $90 ^P/1 красный цвет вывода GRNSYM EQU $91 ^Q/2 зеленый YELSYM EQU $92 ^R/3 желтый BLUSYM EQU $93 ^S/4 синий VIOSYM EQU $94 ^T/5 фиолетовый RGHTSYM EQU $95 ^U/-> вправо курсор SCUPSYM EQU $96 ^V скролл конца экрана вверх SCDNSYM EQU $97 ^W скролл конца экрана вниз UPSYM EQU $99 ^Y/ вверх курсор DOWNSYM EQU $9A ^Z/ вниз курсор NAVSYM EQU $9C ^\/ф6 голубой цвет вывода WHTSYM EQU $9D ^]/ф7 белый цвет вывода EOLSYM EQU $9E ^^/ф8 очист.конец строки EOPSYM EQU $9F ^_/ф9 очист.конец экрана ; ; - ввод символа (ALTSYM+..): CAPSSYM EQU $84 ^D/F1 смена верх.регистра ALTSYM EQU $85 ^E/F2 граф/альт.регистр ; ALT $81 ^A/ф0 шрифт.показ малых букв ; ALT $82 ^B/ф. цвет.выделение малых букв ; ALT $83 ^C/ф= симв/граф.показ упр.символов ; ALT $84 ^D/F1 фиксация регистра/алфавита ; ALT $85 ^E/F2 фиксация граф.регистра ; ALT $86 ^F/F3 показ текст/граф.экрана ; ;ввод строки: SCRSYM EQU $86 F3 перекл.режима экрана ;LEFTSYM EQU $88 ^H к след.символу ;RETSYM EQU $8D ^M конец ввода DELSYM EQU $90 ^P стирание символа INSSYM EQU $91 ^R режим вставки/замены ;RGHTSYM EQU $95 ^U к пред.символу CTRLSYM EQU $96 ^V ввод упр-символа BEGSYM EQU UPSYM к началу строки ENDSYM EQU DOWNSYM к концу строки ESCSYM EQU $9B ^[ смена режима ;EOLSYM EQU $9E ^^ сброс хвоста строки SBTL 'ПОСТОЯННЫЕ ЯЧЕЙКИ НА 0 СТРАНИЦЕ' ; Параметры текстового экрана: STDSCRN EQU $800 -FFF станд.экран INVFLG EQU $32 тек.цвета символа TXPAGE EQU $33 нач.стр.экранной памяти ; окно WNDLFT EQU $20 левый отступ в байтах WNDWDTH EQU $21 ширина в символах WNDTOP EQU $22 верх.строка WNDBTM EQU $23 ниж.строка+1 CH EQU $24 X-коорд.курсора в окне (символ) CV EQU $25 Y-коорд.курсора в экране (строка) BASLIN EQU $28 -29 адрес тек.строки ; Параметры графического экрана: GRPAGE EQU $38 нач.стр.граф.экрана GRMODE EQU $39 граф.режим (см.графику) ; Прочие RND EQU $34 -35 случайное число STINBUF EQU $200 до IOSUB - станд.буфер строки ; Ячейки 26-27,2A-31,36-37 - рабочие драйверов I/O,ДОС SBTL 'ВЕКТОРА ВНУТРИСИСТЕМНОГО ИНТЕРФЕЙСА' IOSUB:: *-- ВЕКТОР ДРАЙВЕРА ПРИНТЕРА ; вх/вых: A=выдаваемый байт ; CALLPRINT:: JSR MEMCALL в дальний DFB OZU1!DBLB банк памяти JSR LP <- адрес драйвера LP RTS не JMP! *-- ВЕКТОР ВЫЗОВА ФУНКЦИИ КОМАНДЕРА ; Интерфейс - в COMMAND.DEF ; CMDHAND EQU $FFF4 CALLCMD:: JSR MEMCALL в дальний банк DFB PZU1!DBLB памяти JSR CMDHAND не JMP! RTS *-- ВЕКТОР ВЫЗОВА ФУНКЦИИ ДОС ; Интерфейс и р.области - в DOS.DEF ; DOS EQU $AB60 CALLDOS:: JSR MEMCALL в дальний банк памяти DFB OZU1!DBLB JSR DOS не JMP! RTS *-- Номер версии IOSUB: ; [7]=0/1: A7/9; [6]=0/1: не/полный з/ген. ; VERSION:: IF A7 DFB $03 ELSE A9 DFB $03!$80 ENDIF SBTL 'ОБРАБОТКА ПРЕРЫВАНИЙ' *-- Разбор типа прерывания IRQ: ; IRQHAND:: STA ACC PLA PHA AND #:00010000 CMP #:00010000 ACC EQU *+1 LDA #0 BCC IRQVECT *-- Вектора обработчиков: ; BRKVECT:: JMP RTI BRK-команда RSTVECT:: JMP RESTART Сброс IRQVECT:: JMP RTI IRQ NMIVECT:: JMP RTI NMI *-- Вкл/выкл.таймерных прерываний IRQ/NMI: ; IRPTON:: STA IRPT1 На старых А-7 - наоборот: RTS константы опред-ет конфигуратор IRPTOFF:: STA IRPT2 RTS SBTL 'УПРАВЛЕНИЕ БАНКАМИ A7-ПАМЯТИ' * А7: Адреса слотов OЗУ и ПЗУ заносятся * в RAMSTAT+2,ROMSTAT+2,SETRAM+2,SETROM+2/-2 * конфигуратором системы *-- Выдача состояния А7-памяти ; вх: X = N сегмента (для А9 не нужен) ; вых: A = код банка в сегменте (А7/9-зависимо), ; X,Y сохр. ; RAMSTAT:: IF A7 LDA $C100,X А7-конфиг:CX00 ELSE LDA $C140 А9-конфиг:4 банк ENDIF RTS ROMSTAT: IF A7 LDA $C100,X А7-конфиг:CX00 ELSE LDA $C160 А9-конфиг:6 банк ENDIF RTS *-- Переключение банков памяти: ; вх: (ROM)C=0/1 - D0/D1 ; вых: X = новое состояние, A,X,Y сохр. ; ; Универсальное для А7-структуры: RAM1:: LDX #OZU1 DFB BIT3 RAM2:: LDX #OZU2 IF A7 BIT NOP1 3 быстрых NOP ELSE A9 SETB2 STA $C111,X смежный А9-банк ENDIF ; Машинно-зависимое: SETRAM:: STA $C100,X A7:CX00 RTS ; Универсальное для А7-структуры: ROM1:: LDX #PZU1 Универс.А7-структура DFB BIT3 ROM2:: LDX #PZU2 IF A7 BCC SETROM STA $C100+DBANK,X A7:CX00 RTS ; Машинно-зависимое: только для А7! SETROM:: STA $C100,X A7:CX00 RTS ELSE A9 STA $C083 переключение D0/D1 BCC SETB2 STA $C08B BCS SETB2 /J ENDIF *-- Обращение к другому банку памяти: ; JSR MEMCALL ; DFB <код банка памяти> ; <3 байта: команда для исполнения> ; (из команд перехода-только JSR) ; все регистры при переключении сохр-ся ! ; разрешен рекурсивный вызов ; MEMCALL:: JMP MEMCALL1 SBTL 'КАНАЛЫ ПОТОКОВ ПОСЛЕДОВАТЕЛЬНОГО I/O' CNLSTAT:: DFB :11010000 флаги I/O:PQRSTUVW *-- Подпрограммы обмена с каналом: ; CNL.P:: DS 2*3+2 <- наполнение потоков: CNL.Q:: DS 2*3+2 вектора драйверов CNL.R:: DS 1*3 CNL.S:: DS 3*3+1 CNL.T:: DS 1*3 CNL.U:: DS 1*3 CNL.V:: DS 1*3 CNL.W:: DS 1*3 *-- Универсальный обмен с настройкой на канал: ; вх: (O:A-символ), ; INX,OUTX: X - номер канала (P-W:10-17), ; IN,OUT: с тек-м настроенным каналом ; вых: (I:A-символ) ; CNLOUTX:: PHA LDA CNLS-$10,X STA CNLOUT+1 PLA CNLOUT:: JMP CNL.S <-- адрес канала CNLINX:: PHA LDA CNLS-$10,X STA CNLIN+1 PLA CNLIN:: JMP CNL.S <-- адрес канала CNLS DFB CNL.P,CNL.Q,CNL.R,CNL.S DFB CNL.T,CNL.U,CNL.V,CNL.W SBTL 'СТАНДАРТНЫЕ ДРАЙВЕРЫ КОНСОЛИ' * Адреса CONIN и CONOUT заносятся * при настройке в буфера каналов GLINE TXA ввод след.строки в буфер PHA TYA PHA JSR GETLNST LDA #>STINBUF STA CONIN+1 PLA TAY PLA TAX CONIN:: LDA STINBUF+00 <-- тек.ук-ль в буфере INC CONIN+1 CMP #RETSYM BEQ GLINE RTS ;CONOUT:: EQU SCROUT SBTL 'ВЕКТОРА ПРЯМОГО ВВОДА С КЛАВИАТУРЫ' *-- Ввод символа (->А) с клавиатуры: ; X,Y сохраняются ; RDKEY0:: LDA #0 без курсора DFB BIT3 RDKEY_:: LDA #'_' со станд-м курсором RDKEYA:: STA CURSOR с курсором в A KEYIN:: JMP KBDIN без сброса строба CURSOR:: DFB '_' текущий курсор *-- Ввод строки (до 255 байт) ; вх: AX = адрес буфера (станд=STINBUF) ; Y = mах.длина строки ; C = 0/1: не/восст. пред.текст ; вых: Y = ук-ль ПC в буфере ; GETLNST:: CLC LDA #STINBUF LDY #>IOSUB-STINBUF GETLINE:: JSR MEMCALL DFB PZU1!DBLB JSR GETLNST1 <- сменный вектор RTS *-- Фильтр упр.символов ввода строки: ; вх/вых: A-упр.символ ; GLNFILT:: JMP NOP1 GLNFLG:: DFB 0 символ оконч.ввода строки SBTL 'ВЕКТОРА ПРЯМОГО ВЫВОДА НА ЭКРАН' * На входе: A=выдаваемый байт * Все программы сохраняют X,Y *-- Вывод HEX-байта/цифры A: ; BYTEOUT:: PHA LSR A LSR A LSR A LSR A JSR PRH PLA DIGOUT:: AND #$0F PRH ORA #'0' CMP #'9'+1 BCC CHAROUT ADC #6 (7) *-- Дополн.внепотоковый вектор вывода: ; CHAROUT:: JMP SCROUT <-- драйвер *-- Перевод строки: вывод ПC на тек.у-во ; CROUT1:: JSR CLREOL с очисткой хвоста строки CROUT:: LDA #RETSYM BNE CHAROUT /J SBTL 'ВСПОМОГАТЕЛЬНЫЕ ПРОГРАММЫ' *-- Станд. пауза: 13+27/2*A+512*A*A мксек: ; вых: A=0, X,Y сохр. ; WAIT:: SEC WT2 PHA WT3 SBC #1 BNE WT3 PLA SBC #1 BNE WT2 RTS *-- Перезапуск машины: ; RESTART:: IF A7 LDX #PZU1%PZUWR JSR SETROM ELSE A9 STA $C081 mоnitоr NOP NOP ENDIF JMP ($FFFC) в сист.монитор SBTL 'УПРАВЛЕНИЕ РЕЖИМАМИ ОТОБРАЖЕНИЯ ЭКРАНА' *-- Сброс экрана в станд.состояние: ; SETSCRN:: LDA #$80!NORMLB!GRNCLR цвет вывода & АЦР64 STA INVFLG LDA #граф.символы ;.. RTS *-- Формирование кода символа по коду клавиши ; и состоянию регистров: ; графсимволы от регистров не зависят ; вх: A=код клавиши ([7]=1,[6]=рег), KBDREG[7]-алфавит ; вых: A=код символа ; KEYCODE:: CMP #$C0 BCC KC3 CMP #$E0 BCC KC1 EOR KBDMFLG KC1 BIT KBDREG BMI KC2 EOR #$A0 смена регистра+алфавита KC2 EOR CAPSFLG AND GRPHFLG KC3 RTS NOP *** SETCAPS LDA #$80 уст-ка регистров SETMODE CMP #$86 (коды 80-86) BCS KFR STY YSAV TAY LDA TOGGL-$80,Y EOR FLAGS-$80,Y STA FLAGS-$80,Y LDY YSAV LDA #CAPSSYM -неотобр.символ KFR RTS TOGGL DFB $80,$80,$04,$20,$A0,$C0 модификаторы FLAGS CAPSFLG:: DFB $00 /80 состояние верх.регистра FONTFLG:: DFB $00 /80 выделение строчных COLRFLG:: DFB $00 /04 подсветка CTRL-ов CTRLFLG:: DFB $A0 /80 отображение CTRL-ов KBDMFLG:: DFB $A0 /00 фиксация регистра/алфавита GRPHFLG:: DFB $FF /3F граф.регистр SBTL 'ПРЯМОЙ ВЫВОД НА ЭКРАН' BAS2L EQU $2A -2B Рабочие ячейки YSAV1 EQU $2C - SCROUT INCR EQU $2D - SCROLL LIM EQU $2E - SCROLL *-- Вывод символа на экран ; вх: A = символ ; вых: A,X,Y сохр, PSW настроено по A ; CONOUT:: SCROUT:: PHA STY YSAV1 JSR CTRLOUT LDY YSAV1 PLA RTS *-- Разбор упр.символов и вывод символа ; CTRLOUT TAY BPL STORADV CMP #' ' BCS STORADV LDY #C=0 STX BAS2L TAX CLRC LDA #' ' STA (BASLIN),Y INY LDA INVFLG BMI CLZ STA (BASLIN),Y INY CLZ INX BNE CLRC LDX BAS2L BCC VTAB /J -восст BASLIN тек.строки *-- Сдвиг экрана (sсrоll) ; вых: сохр.X, CH,CV ; SCRLDN:: LDY WNDBTM Вниз от CV DEY TYA - нач.строка LDY CV - кон.строка DEY STY LIM LDY #$FF - шаг BNE SCOMN /J SCROLL:: LDA WNDTOP Вверх к верх.краю DFB BIT3 SCRLUP:: LDA CV Вверх к CV LDY WNDBTM - кон.строка STY LIM LDY #1 - шаг SCOMN STY INCR PHA JSR VTABZ ->C=0 SCRL1 LDA BASLIN STA BAS2L LDA BASLIN+1 STA BAS2L+1 LDA WNDWDTH JSR CALCHZ PLA ADC INCR C=0 CMP LIM BEQ CLRLINE выход отсюда PHA JSR VTABZ SCRL2 DEY BMI SCRL1 LDA (BASLIN),Y STA (BAS2L),Y BCC SCRL2 /J *-- Установка цвета INVFLG: ; вх: Y[2:0] - новый цвет SETCOLOR:: TYA EOR INVFLG AND #7 STFL EOR INVFLG STA INVFLG RTS *-- Исполнение управ.функций ; вх: A-символ ; CALLTAB: CMP TABCTRL,Y BEQ CALL INY BCS CALLTAB пока < LDY #7 CCOL CMP TCOLORS-1,Y сравнение с цветами BEQ SETCOLOR DEY BNE CCOL RTS CALL LDA ADRCTRL,Y STA BAS2L JMP (BAS2L) TCOLORS DFB REDSYM,GRNSYM,YELSYM DFB BLUSYM,VIOSYM,NAVSYM DFB WHTSYM ; управляющие символы (по возр): TABCTRL: GETCTRL: DFB SCRSYM,LEFTSYM,RETSYM ввод строки DFB DELSYM,INSSYM,RGHTSYM DFB CTRLSYM,BEGSYM,ENDSYM DFB ESCSYM,EOLSYM ; SYMCTRL: DFB NORMSYM,INVSYM,FLSHSYM вывод символа DFB BELLSYM,LEFTSYM,HOMESYM DFB CLSSYM,RETSYM,CLINSYM DFB RGHTSYM,SCUPSYM,SCDNSYM DFB UPSYM,DOWNSYM,EOLSYM DFB EOPSYM ; >адреса программ: (все на 1 стр!) ADRCTRL: DFB GTXGR,GBACK,GEXIT DFB GDEL,GINRP,GADV DFB GINSC,GBEG,GEND DFB GESC,GCUT ; DFB SETNORM,SETINV,SETFLSH DFB BELL,BS,HOME DFB CLS,NEWLINE,CLRLINE DFB ADVANCE,SCRLUP,SCRLDN DFB UP,DOWN,CLREOL DFB CLREOP *-- Чтение точки окна ; вх: A = номер строки, Y = номер поз. ; вых: A = символ, Y = цвет (кроме ГHC) ; тек.позиция не меняется ; READSCRN:: JSR VTABZ TYA JSR CALCHZ LDA (BASLIN),Y PHA INY LDA (BASLIN),Y TAY JSR VTAB PLA RTS *-- Вычисление адреса экранной строки ; вх: A = N строки ; вых: BASLIN = адрес, X,Y сохр. ; BASCALC:: STA BASLIN+1 LDA #0 LSR BASLIN+1 ROR A LSR BASLIN+1 ROR A STA BASLIN LDA TXPAGE ADC BASLIN+1 C=0 STA BASLIN+1 RTS SBTL 'ВВОД С ПОТЕНЦИОМЕТРОВ' *-- Опрос состояния ручки ; вх: X = 1/2 -номер ; вых: A = Y - 256 разл.значений PADDLE:: LDA PDLTRIG LDY #0 PREAD LDA PDLREG-1,X BPL PRD INY BNE PREAD DEY PRD TYA RTS *-- Опрос состояния кнопки ; вх: X = 1/2 -номер ; вых: C = 0/1 -нажата, A=?, Y сохр. ; BUTTON:: ASL BTNREG-1,X RTS SBTL 'МАШИННО-ЗАВИСИМЫЙ МЕЖБАНКОВЫЙ ВЫЗОВ' SA EQU $2A рабочие! SX EQU $2B SPSW EQU $2C MEMCALL1:: JSR RGSAV TSX доступ к банку/команде INX после вызова ч/з стек LDA $100,X STA RDI+1 CLC ADC #4 STA $100,X INX LDA $100,X STA RDI+2 ADC #0 STA $100,X LDX #4 RDI LDA $FFFF+1,X DEX BEQ CS STA CMD-1,X BPL RDI /J CS JSR SWITCH PHA JSR RGRST CMD DS 3 <-пишется команда JSR RGSAV PLA JSR SWITCH RGRST LDA SPSW восст.рег-в PHA не меняет S! LDX SX LDA SA PLP RTS RGSAV STA SA сохр.рег-в STX SX не меняет S! PHP PLA STA SPSW RTS SWITCH:: IF A7 TAX BPL SWRAM JSR ROMSTAT JMP SETROM DS 5 SWRAM JSR RAMSTAT JMP SETRAM ELSE A9 TAX BPL SWB1 N:1/2банка AND #$7F TAX LDA $C100,X ORA #$80 JMP SETB2 SWB1 LDA $C100,X JMP SETRAM ENDIF SBTL 'ВВОД СТРОКИ С КЛАВИАТУРЫ' INBUF EQU $26 -27 буфер ввода LFT EQU $2E WLFT EQU $2F MAX EQU $30 CURY EQU $31 *-- Ввод строки с клавиатуры в буфер: ; Здесь фильтр не настраивается! ; вх: Y = mах.длина строки ; AX = буфер длины Y+1 ; C = 0/1: не/восст. пред.текст ; вых: Y = факт.длина, (INBUF),Y = RETSYM ; GLNFLG = символ выхода ; GETLNST1:: STX INBUF STA INBUF+1 DEY STY MAX JSR GMRK ПС в конец буфера LDA CH STA WLFT LDA #0 STA CT+1 STA CURY STA LFT LDA #BEGSYM восст.пред.текст BCS GN GNEXT JSR KEYIN GN STA GLNFLG JSR GFILT JSR GOUT SEC ROR CT+1 /=0 BMI GNEXT /J ; Отработка символов: GFILT TAY BPL GINS CMP #' ' BCS GINS ; LDY #C=0/1 не/конец строки BCC GOC BCS GEO /J GCL JSR CLREOL GEO PLA STA CH LDY CURY RTS ; Смена режима вставки/замены: GINRP LDA IR EOR #$20%$AD JSR/LDA STA IR RTS GTXGR JMP GR.TEXT DS $800-* контроль запаса