Mercurial > hg > Members > kono > nitros9-code
view level1/atari/modules/vtio.asm @ 2736:31cd1f1b4fb0 lwtools-port
Added ClrScrn and CapsLock functionality for Atari VTIO
author | Boisy Pitre <boisy.pitre@nuance.com> |
---|---|
date | Mon, 10 Dec 2012 16:27:38 -0600 |
parents | 8399491c0821 |
children |
line wrap: on
line source
******************************************************************** * VTIO - NitrOS-9 Video Terminal I/O driver for Atari XE/XL * * $Id$ * * Edt/Rev YYYY/MM/DD Modified by * Comment * ------------------------------------------------------------------ * 1 2012/02/20 Boisy G. Pitre * Started from VTIO for the Atari XE/XL nam VTIO ttl NitrOS-9 Video Terminal I/O driver for Atari XE/XL ifp1 use defsfile use atarivtio.d endc tylg set Drivr+Objct atrv set ReEnt+rev rev set $00 edition set 1 mod eom,name,tylg,atrv,start,size size equ V.Last fcb UPDAT.+EXEC. name fcs /VTIO/ fcb edition start lbra Init lbra Read lbra Write lbra GetStat lbra SetStat lbra Term * The display list sets up the ANTIC chip to display the main screen. * It is copied to the Atari Screen Area in low memory (see atari.d) * The size of this code MUST be <= G.DListSize *DList * fcb $70,$70,$70 3 * 8 blank scanlines * fcb $42 Mode 2 with LMS (Load Memory Scan). Mode 2 = 40 column hires text, next 2 bytes L/H determine screen origin * fdbs G.ScrStart+(G.Cols*0) origin * fcb 2,2,2,2,2,2,2,2,2,2 * fcb 2,2,2,2,2,2,2,2,2,2 * fcb 2,2,2 * 23 extra mode 2 lines for total of 24. 240 scanlines can be used for display area, but a hires line cannot be on scanline 240 due to an Antic bug * fcb $41 this is the end of Display List command JVB (Jump and wait for Vertical Blank) * fdb $0000 *DListSz equ *-DList * Init * * Entry: * Y = address of device descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Init stu >D.KbdSta store devmem ptr pshs u leax ChkSpc,pcr stx V.EscVect,u * setup static vars clra clrb std V.CurRow,u * Clear screen memory ldy #G.ScrEnd pshs y ldy #G.ScrStart ldd #$0000 clearLoop@ std ,y++ cmpy ,s bne clearLoop@ puls u G.DList address is aleady in U * copy the display list into our memory area to the global location in low RAM * leax DList,pcr * ldy #DListSz *dlcopy@ * ldd ,x++ * std ,u++ * leay -2,y * bne dlcopy@ * patch last word to be address of start of DList (byte swap for ANTIC) * leau -DListSz,u * tfr u,d * exg a,b * std DListSz-2,u * tell the ANTIC where the dlist is * std DLISTL * tell the ANTIC where the character set is (page aligned, currently in Krn) * lda #G.CharSetAddr>>8 * sta CHBASE * set background color clra sta COLBK * set text color lda #$0F sta COLPF1 lda #$94 sta COLPF2 * tell ANTIC to start DMA * lda #$22 * sta DMACTL * tell ANTIC to enable character set 2 * lda #$02 * sta CHACTL * install keyboard ISR ldd #IRQST POKEY IRQ status address leay IRQSvc,pcr pointer to our service routine leax IRQPkt,pcr F$IRQ requires a 3 byte packet ldu ,s use our saved devmem as ISR static os9 F$IRQ install the ISR bcs initex * set POKEY to active lda #$13 sta SKCTL * tell POKEY to enable keyboard scanning lda #(IRQST.BREAKDOWN|IRQST.KEYDOWN) pshs cc orcc #IntMasks ora >D.IRQENSHDW sta >D.IRQENSHDW puls cc sta IRQEN * clear carry and return clrb initex puls u,pc * Term * * Entry: * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Term * clear carry and return clrb rts * Read * * Entry: * Y = address of path descriptor * U = address of device memory area * * Exit: * A = character read * CC = carry set on error * B = error code * Read leax V.InBuf,u point X to input buffer ldb V.IBufT,u get tail pointer orcc #IRQMask mask IRQ cmpb V.IBufH,u same as head pointer beq Put2Bed if so, buffer is empty, branch to sleep abx X now points to curr char lda ,x get char bsr cktail check for tail wrap stb V.IBufT,u store updated tail andcc #^(IRQMask+Carry) unmask IRQ rts Put2Bed lda V.BUSY,u get calling process ID sta V.WAKE,u store in V.WAKE andcc #^IRQMask clear interrupts ldx #$0000 os9 F$Sleep sleep forever clr V.WAKE,u clear wake ldx <D.Proc get pointer to current proc desc ldb <P$Signal,x get signal recvd beq Read branch if no signal cmpb #S$Window window signal? bcc Read branch if so coma rts * Check if we need to wrap around tail pointer to zero cktail incb increment pointer cmpb #KBufSz-1 at end? bls readex branch if not * clear carry and return clrb else clear pointer (wrap to head) readex rts * Write * * Entry: * A = character to write * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Write bsr hidecursor ldx V.EscVect,u jsr ,x bra drawcursor ChkSpc cmpa #C$SPAC space or greater? bcs ChkESC branch if not wchar suba #$20 pshs a lda V.CurRow,u ldb #G.Cols mul addb V.CurCol,u adca #0 ldx #G.ScrStart leax d,x puls a sta ,x ldd V.CurRow,u incb cmpb #G.Cols blt ok clrb incrow inca cmpa #G.Rows blt clrline SCROLL EQU 1 IFNE SCROLL deca set A to G.Rows - 1 pshs d save off Row/Col ldx #G.ScrStart get start of screen memory ldy #G.Cols*(G.Rows-1) set Y to size of screen minus last row scroll_loop ldd G.Cols,x get two bytes on next row std ,x++ store on this row leay -2,y decrement Y bne scroll_loop branch if not 0 puls d recover Row/Col ELSE clra ENDC * clear line clrline std V.CurRow,u bsr DelLine rts ok std V.CurRow,u ret rts * calculates the cursor location in screen memory * Exit: X = address of cursor * All other regs preserved calcloc pshs d lda V.CurRow,u ldb #G.Cols mul addb V.CurCol,u adca #0 ldx #G.ScrStart leax d,x puls d,pc drawcursor bsr calcloc lda ,x sta V.CurChr,u lda #$80 sta ,x rts hidecursor pshs a bsr calcloc lda V.CurChr,u sta ,x puls a,pc ChkESC cmpa #$1B ESC? lbeq EscHandler cmpa #$0D $0D? bhi ret branch if higher than leax <DCodeTbl,pcr deal with screen codes lsla adjust for table entry size ldd a,x get address in D jmp d,x and jump to routine * display functions dispatch table DCodeTbl fdb NoOp-DCodeTbl $00:no-op (null) fdb CurHome-DCodeTbl $01:HOME cursor fdb CurXY-DCodeTbl $02:CURSOR XY fdb DelLine-DCodeTbl $03:ERASE LINE fdb ErEOLine-DCodeTbl $04:CLEAR TO EOL fdb Do05-DCodeTbl $05:CURSOR ON/OFF fdb CurRght-DCodeTbl $005e $06:CURSOR RIGHT fdb NoOp-DCodeTbl $07:no-op (bel:handled in VTIO) fdb CurLeft-DCodeTbl $08:CURSOR LEFT fdb CurUp-DCodeTbl $09:CURSOR UP fdb CurDown-DCodeTbl $0A:CURSOR DOWN fdb ErEOScrn-DCodeTbl $0B:ERASE TO EOS fdb ClrScrn-DCodeTbl $0C:CLEAR SCREEN fdb Retrn-DCodeTbl $0D:RETURN DelLine lda V.CurRow,u ldb #G.Cols mul ldx #G.ScrStart leax d,x lda #G.Cols clrloop@ clr ,x+ deca bne clrloop@ rts ClrScrn clr V.CurCol,u lda #G.Rows-1 clrloop@ sta V.CurRow,u pshs a bsr DelLine puls a deca bpl clrloop@ clr V.CurCol,u rts ErEOScrn CurUp NoOp CurHome clr V.CurCol,u clr V.CurRow,u rts CurXY ErEOLine Do05 CurRght rts CurLeft ldd V.CurRow,u beq leave decb bpl erasechar ldb #G.Cols-1 deca bpl erasechar clra erasechar std V.CurRow,u ldb #G.Cols mul addb V.CurCol,u adca #0 ldx #G.ScrStart leax d,x clr 1,x leave rts CurDown ldd V.CurRow,u lbra incrow Retrn clr V.CurCol,u rts EscHandler leax EscHandler2,pcr eschandlerout stx V.EscVect,u rts EscHandler2 sta V.EscCh1,u leax EscHandler3,pcr bra eschandlerout EscHandler3 ldb V.EscCh1,u cmpb #$32 beq DoFore cmpb #$33 beq DoBack cmpb #$34 beq DoBord eschandler3out leax ChkSpc,pcr bra eschandlerout DoFore * sta COLPF0 sta COLPF1 * sta COLPF3 bra eschandler3out DoBack sta COLPF2 bra eschandler3out DoBord sta COLBK bra eschandler3out * GetStat * * Entry: * A = function code * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * GetStat cmpa #SS.ScSiz bne gserr ldx PD.RGS,y ldd #G.Cols std R$X,x ldd #G.Rows std R$Y,x * clear carry and return clrb rts gserr comb ldb #E$UnkSvc rts * SetStat * * Entry: * A = function code * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * SetStat * clear carry and return clrb rts IRQPkt equ * Pkt.Flip fcb (IRQST.BREAKDOWN|IRQST.KEYDOWN) flip byte Pkt.Mask fcb (IRQST.BREAKDOWN|IRQST.KEYDOWN) mask byte fcb $0A priority * * IRQ routine for keyboard * IRQSvc * check if BREAK key pressed; if so, it's a C$QUIT char ldb IRQST bitb #IRQST.BREAKDOWN bne getcode lda #C$QUIT bra noctrl@ getcode ldb KBCODE get keyboard code from POKEY gotcode pshs b andb #$7F mask out potential CTRL key leax ATASCI,pcr lda b,x fetch character for code tst ,s+ CTRL key down? bpl noctrl@ branch if not cmpa #$40 bcs noctrl@ anda #$5F suba #$40 noctrl@ * check for caps lock cmpa #$82 bne tst4caps@ tst V.CapsLck,u beq turnon@ clra turnon@ sta V.CapsLck,u bra KeyLeave tst4caps@ tst V.CapsLck,u beq goon@ cmpa #$61 blt goon@ cmpa #$7a bgt goon@ suba #$20 goon@ ldb V.IBufH,u get head pointer in B leax V.InBuf,u point X to input buffer abx X now holds address of head lbsr cktail check for tail wrap cmpb V.IBufT,u B at tail? beq L012F branch if so stb V.IBufH,u L012F sta ,x store our char at ,X beq WakeIt if nul, do wake-up cmpa V.PCHR,u pause character? bne L013F branch if not ldx V.DEV2,u else get dev2 statics beq WakeIt branch if none sta V.PAUS,x else set pause request bra WakeIt L013F ldb #S$Intrpt get interrupt signal cmpa V.INTR,u our char same as intr? beq L014B branch if same ldb #S$Abort get abort signal cmpa V.QUIT,u our char same as QUIT? bne WakeIt branch if not L014B lda V.LPRC,u get ID of last process to get this device bra L0153 go for it WakeIt ldb #S$Wake get wake signal lda V.WAKE,u get process to wake L0153 beq L0158 branch if none os9 F$Send else send wakeup signal L0158 clr V.WAKE,u clear process to wake flag * Update the shadow register then the real register to disable and * re-enable the keyboard interrupt KeyLeave pshs cc orcc #IntMasks lda >D.IRQENShdw tfr a,b anda #^(IRQST.BREAKDOWN|IRQST.KEYDOWN) orb #(IRQST.BREAKDOWN|IRQST.KEYDOWN) sta IRQEN stb >D.IRQENShdw stb IRQEN puls cc,pc ATASCI fcb $6C,$6A,$3B,$80,$80,$6B,$2B,$2A ;LOWER CASE fcb $6F,$80,$70,$75,$0D,$69,$2D,$3D fcb $76,$80,$63,$80,$80,$62,$78,$7A fcb $34,$80,$33,$36,$1B,$35,$32,$31 fcb $2C,$20,$2E,$6E,$80,$6D,$2F,$81 fcb $72,$80,$65,$79,$7F,$74,$77,$71 fcb $39,$80,$30,$37,$08,$38,$3C,$3E fcb $66,$68,$64,$80,$82,$67,$73,$61 fcb $4C,$4A,$3A,$80,$80,$4B,$5C,$5E ;UPPER CASE fcb $4F,$80,$50,$55,$9B,$49,$5F,$7C fcb $56,$80,$43,$80,$80,$42,$58,$5A fcb $24,$80,$23,$26,$1B,$25,$22,$21 fcb $5B,$20,$5D,$4E,$80,$4D,$3F,$81 fcb $52,$80,$45,$59,$9F,$54,$57,$51 fcb $28,$80,$29,$27,$9C,$40,$7D,$9D fcb $46,$48,$44,$80,$83,$47,$53,$41 * fcb $0C,$0A,$7B,$80,$80,$0B,$1E,$1F ;CONTROL * fcb $0F,$80,$10,$15,$9B,$09,$1C,$1D * fcb $16,$80,$03,$80,$80,$02,$18,$1A * fcb $80,$80,$85,$80,$1B,$80,$FD,$80 * fcb $00,$20,$60,$0E,$80,$0D,$80,$81 * fcb $12,$80,$05,$19,$9E,$14,$17,$11 * fcb $80,$80,$80,$80,$FE,$80,$7D,$FF * fcb $06,$08,$04,$80,$84,$07,$13,$01 emod eom equ * end