; read
HW_KBD = 0xc000
+HW_IOUDIS = 0xc07e ; bit7 = IOUDIS state
; write
-HW_CLR80COL = 0xc000
-HW_SET80COL = 0xc001
+HW_CLR80COL = 0xc000 ; aka CLR80STORE, bankswitch by (RD|WR)(CARD|MAIN)RAM
+HW_SET80COL = 0xc001 ; aka SET80STORE, bankswitch by PAGE1/PAGE2, show page 1
HW_CLR80VID = 0xc00c
HW_SET80VID = 0xc00d
HW_KBDSTRB = 0xc010
+HW_SETIOUDIS = 0xc07e ; IIc only, enable access to annunciators
+HW_CLRIOUDIS = 0xc07f ; IIc only, enable access to mouse
; read/write
HW_CLRTEXT = 0xc050
HW_PAGE2 = 0xc055
HW_CLRHIRES = 0xc056
HW_SETHIRES = 0xc057
-HW_SETDHIRES = 0xc05e
-HW_SETIOUDIS = 0xc07e
-HW_CLRIOUDIS = 0xc07f
+HW_SETAN3 = 0xc05e ; enable dhires
+HW_CLRAN3 = 0xc05f ; disable dhires
TEXT_ADDR = 0x400
TEXT_SIZE = 0x400
-DATA_ADDR = 0x880
+DATA_ADDR = 0x900
DATA_FRAMES = 6
+WARM_START = 0x3d0
+ASOFT_GR = 0xf390
+MON_SETTXT = 0xfb39
+MON_HOME = 0xfc58
+
.area zpage
.setdp
.ds 0x80
src: .ds 2
dest: .ds 2
+count: .ds 1
.area text
- sta HW_CLR80COL
+ sta HW_SET80COL
sta HW_SET80VID
+
+ lda HW_IOUDIS
+ sta HW_SETIOUDIS
+ sta HW_SETAN3
+ bmi 0$
sta HW_CLRIOUDIS
+0$:
sta HW_CLRTEXT
sta HW_CLRMIXED
- sta HW_PAGE1
sta HW_CLRHIRES
- sta HW_SETDHIRES
-
- sta HW_SET80COL ; use HW_PAGE1/HW_PAGE2 for bank switching
lda #<DATA_ADDR
sta src
sta dest + 1
; copy one screen (there are 8 lines in 1/3 screen)
- ldx #8
-copy:
+ lda #8
+ sta count
+copy_screen:
- ; copy 3 lines 8 lines apart to page 1, stop at screen hole
- sta HW_PAGE1
- ldy #119
-copy0: lda [src],y
+ ; copy 3 lines 8 lines apart
+ ldx #3
+ clc
+copy_line:
+
+ ldy #39
+0$: lda [src],y
sta [dest],y
dey
- bpl copy0
+ bpl 0$
- ; src += 0x80
+ ; src += 40
lda src
- eor #0x80
+ adc #40
sta src
- bmi 0$
- inc src + 1
-0$:
- ; copy 3 lines 8 lines apart to page 2, stop at screen hole
+ sei ; disable interrupts while screen holes are wrong
sta HW_PAGE2
- ldy #119
-copy1: lda [src],y
+
+ ldy #39
+1$: lda [src],y
sta [dest],y
dey
- bpl copy1
+ bpl 1$
- ; src += 0x80
+ sta HW_PAGE1
+ cli
+
+ ; src += 40
lda src
- eor #0x80
+ adc #40
+ sta src
+
+ ; dest += 40
+ lda dest
+ adc #40
+ sta dest
+
+ dex
+ bne copy_line
+
+ ; src += 16 (always carries)
+ lda #<DATA_ADDR ; always 0 in practice
sta src
- bmi 0$
inc src + 1
-0$:
- ; dest += 0x80
+ ; dest += 8 (might carry)
lda dest
- eor #0x80
+ adc #8
sta dest
- bmi 1$
+ bcc 2$
inc dest + 1
-1$:
+2$:
- dex
- bne copy
+ dec count
+ bne copy_screen
; delay (assumes x == 0)
ldy #0x30
-2$: dex
- bne 2$
+delay: dex
+ bne delay
+
+ lda HW_KBD
+ bmi quit
+
dey
- bne 2$
+ bne delay
; wrap
lda src + 1
cmp #>(DATA_ADDR + DATA_FRAMES * TEXT_SIZE)
bcc loop
bcs reset
+
+quit: sta HW_KBDSTRB
+
+ sta HW_CLR80VID
+ sta HW_CLR80COL
+
+ lda HW_IOUDIS
+ sta HW_SETIOUDIS
+ sta HW_CLRAN3
+ bmi 0$
+ sta HW_CLRIOUDIS
+0$:
+
+ lda HW_SETTEXT
+ lda HW_PAGE1
+
+ jsr MON_SETTXT
+ jsr MON_HOME
+ jmp WARM_START
transparent_color = image_in[0, 0, 0] # temporary
image_in[image_in == transparent_color] = 0
-# rotate colours in aux memory (required by the hardware)
-image_in[:, :, 0::2] = \
- (image_in[:, :, 0::2] >> 1) | ((image_in[:, :, 0::2] << 3) & 8)
-
-image_out = numpy.zeros((ts, 8, 2, 0x80), numpy.uint8)
+image_out = numpy.zeros((ts, 8, 0x100), numpy.uint8)
shifts = [0, 4]
planes = [1, 0]
-for i in range(ys):
- for j in range(2):
- image_out[:, (i >> 1) & 7, j, (i >> 4) * 40:((i >> 4) + 1) * 40] |= \
- image_in[:, i, planes[j]::2] << shifts[i & 1]
+for i in range(3):
+ for j in range(8):
+ for k in range(2):
+ # main memory
+ image_out[:, j, i * 80:i * 80 + 40] |= (
+ image_in[:, k | (j << 1) | (i << 4), 1::2]
+ ) << (k << 2)
+ # aux memory (colours are rotated by 1 bit)
+ image_out[:, j, i * 80 + 40:i * 80 + 80] |= (
+ (image_in[:, k | (j << 1) | (i << 4), 0::2] >> 1) |
+ ((image_in[:, k | (j << 1) | (i << 4), 0::2] << 3) & 8)
+ ) << (k << 2)
image_out = image_out.reshape((ts * 0x800,))
intelhex = IntelHex()