; ; 2022-04-02, Karri Kaksonen ; ; The Atari 7800 has only 4k of RAM. So for a generic conio implementation ; the best alternative is to use indirect tile mapping with a character ; frame buffer ; .constructor initconio .include "atari7800.inc" .include "extzp.inc" .import _conio_font .import _get_tv .export _screen .export _zones .export _dll .bss _screen: .res charsperline * screenrows ;---------------------------------------------------------------------------- ; Macros used to generate lists .macro DLLentry offset, addr .byte offset .byte >addr .byte addr .byte hpos .endmacro .macro XHeader addr, flags, palwidth, hpos .byte addr .byte palwidth .byte hpos .endmacro .macro TextZone row ; Text .byte <(_screen + row * charsperline) .byte $60 .byte >(_screen + row * charsperline) .byte 12 .byte 0 ; Cursor .byte 254 .byte 0 .byte >_conio_font .byte 0 .endmacro ;----------------------------------------------------------------------------- ; The Atari 7800 has only 4k of RAM. So for a generic conio implementation ; the best alternative is to use indirect tile mapping with a character ; frame buffer .data _zones: zone0: TextZone 0 nh: NullHeader 0, 0 zone1: TextZone 1 NullHeader 0, 0 zone2: TextZone 2 NullHeader 0, 0 zone3: TextZone 3 NullHeader 0, 0 zone4: TextZone 4 NullHeader 0, 0 zone5: TextZone 5 NullHeader 0, 0 zone6: TextZone 6 NullHeader 0, 0 zone7: TextZone 7 NullHeader 0, 0 zone8: TextZone 8 NullHeader 0, 0 zone9: TextZone 9 NullHeader 0, 0 zone10: TextZone 10 NullHeader 0, 0 zone11: TextZone 11 NullHeader 0, 0 zone12: TextZone 12 NullHeader 0, 0 zone13: TextZone 13 NullHeader 0, 0 zone14: TextZone 14 NullHeader 0, 0 zone15: TextZone 15 NullHeader 0, 0 zone16: TextZone 16 NullHeader 0, 0 zone17: TextZone 17 NullHeader 0, 0 zone18: TextZone 18 NullHeader 0, 0 zone19: TextZone 19 NullHeader 0, 0 zone20: TextZone 20 NullHeader 0, 0 zone21: TextZone 21 NullHeader 0, 0 zone22: TextZone 22 NullHeader 0, 0 zone23: TextZone 23 NullHeader 0, 0 zone24: TextZone 24 NullHeader 0, 0 zone25: TextZone 25 NullHeader 0, 0 zone26: TextZone 26 NullHeader 0, 0 zone27: TextZone 27 NullHeader 0, 0 _dll: PALscanlines: ; 25 lines DLLentry 15, nh DLLentry 8, nh Topscanlines: ; 9 lines DLLentry 8, nh Displaylines: DLLentry $80+7, zone0 ; NMI interrupt from end of prev zone DLLentry 7, zone1 DLLentry 7, zone2 DLLentry 7, zone3 DLLentry 7, zone4 DLLentry 7, zone5 DLLentry 7, zone6 DLLentry 7, zone7 DLLentry 7, zone8 DLLentry 7, zone9 DLLentry 7, zone10 DLLentry 7, zone11 DLLentry 7, zone12 DLLentry 7, zone13 DLLentry 7, zone14 DLLentry 7, zone15 DLLentry 7, zone16 DLLentry 7, zone17 DLLentry 7, zone18 DLLentry 7, zone19 DLLentry 7, zone20 DLLentry 7, zone21 DLLentry 7, zone22 DLLentry 7, zone23 DLLentry 7, zone24 DLLentry 7, zone25 DLLentry 7, zone26 DLLentry 7, zone27 Bottomscanlines: DLLentry $80+15, nh ; NMI interrupt at end of display DLLentry 9, nh DLLentry 15, nh DLLentry 8, nh ;----------------------------------------------------------------------------- ; Set up the screen to 320a mode ; .segment "ONCE" CTRL_MODE160 .set 0 CTRL_MODEAC .set 3 CTRL_KANGOFF .set 0 CTRL_BCBLACK .set 0 CTRL_CHAR1B .set 0 CTRL_CHAR2B .set $10 CTRL_DMAON .set $40 CTRL_CKOFF .set 0 ;----------------------------------------------------------------------------- ; Initialize the conio display lists and zones ; .proc initconio jsr _get_tv bne pal lda #Topscanlines sta DPPH jmp vblankon pal: lda #PALscanlines sta DPPH vblankon: lda MSTAT bmi vblankon vblankoff: lda MSTAT bpl vblankoff lda #>_conio_font sta CHBASE lda #(CTRL_MODE160 | CTRL_KANGOFF | CTRL_BCBLACK | CTRL_CHAR2B | CTRL_DMAON | CTRL_CKOFF) sta CTRL lda #$00 ; Black background sta BKGRND sta CURS_X sta CURS_Y lda #$33 ; Red sta P0C1 lda #$c8 ; Green sta P0C2 lda #$0f ; White sta P0C3 rts .endproc