mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-20 18:08:05 +11:00
New kernel module: grid
This commit is contained in:
parent
434c8d5c0d
commit
247b200dcc
@ -16,10 +16,13 @@ Launch the emulator with `./sms /path/to/rom` (you can use the binary from the
|
|||||||
This will show a window with the screen's content on it. The mappings to the
|
This will show a window with the screen's content on it. The mappings to the
|
||||||
pad are:
|
pad are:
|
||||||
|
|
||||||
* Arrows
|
* W --> Up
|
||||||
* Z --> A
|
* A --> Left
|
||||||
* X --> B
|
* S --> Down
|
||||||
* C --> C
|
* D --> Right
|
||||||
* S --> Start
|
* H --> A
|
||||||
|
* J --> B
|
||||||
|
* K --> C
|
||||||
|
* L --> Start
|
||||||
|
|
||||||
Press ESC to quit.
|
Press ESC to quit.
|
||||||
|
@ -180,29 +180,29 @@ void event_loop()
|
|||||||
bool ispressed = e->response_type == XCB_KEY_PRESS;
|
bool ispressed = e->response_type == XCB_KEY_PRESS;
|
||||||
switch (ev->detail) {
|
switch (ev->detail) {
|
||||||
case 0x09: return; // ESC
|
case 0x09: return; // ESC
|
||||||
case 0x27: // S
|
case 0x19: // W
|
||||||
pad_setbtn(&pad, PAD_BTN_START, ispressed);
|
|
||||||
break;
|
|
||||||
case 0x34: // Z
|
|
||||||
pad_setbtn(&pad, PAD_BTN_A, ispressed);
|
|
||||||
break;
|
|
||||||
case 0x35: // X
|
|
||||||
pad_setbtn(&pad, PAD_BTN_B, ispressed);
|
|
||||||
break;
|
|
||||||
case 0x36: // C
|
|
||||||
pad_setbtn(&pad, PAD_BTN_C, ispressed);
|
|
||||||
break;
|
|
||||||
case 0x62:
|
|
||||||
pad_setbtn(&pad, PAD_BTN_UP, ispressed);
|
pad_setbtn(&pad, PAD_BTN_UP, ispressed);
|
||||||
break;
|
break;
|
||||||
case 0x64:
|
case 0x26: // A
|
||||||
pad_setbtn(&pad, PAD_BTN_LEFT, ispressed);
|
pad_setbtn(&pad, PAD_BTN_LEFT, ispressed);
|
||||||
break;
|
break;
|
||||||
case 0x66:
|
case 0x27: // S
|
||||||
|
pad_setbtn(&pad, PAD_BTN_DOWN, ispressed);
|
||||||
|
break;
|
||||||
|
case 0x28: // D
|
||||||
pad_setbtn(&pad, PAD_BTN_RIGHT, ispressed);
|
pad_setbtn(&pad, PAD_BTN_RIGHT, ispressed);
|
||||||
break;
|
break;
|
||||||
case 0x68:
|
case 0x2b: // H
|
||||||
pad_setbtn(&pad, PAD_BTN_DOWN, ispressed);
|
pad_setbtn(&pad, PAD_BTN_A, ispressed);
|
||||||
|
break;
|
||||||
|
case 0x2c: // J
|
||||||
|
pad_setbtn(&pad, PAD_BTN_B, ispressed);
|
||||||
|
break;
|
||||||
|
case 0x2d: // K
|
||||||
|
pad_setbtn(&pad, PAD_BTN_C, ispressed);
|
||||||
|
break;
|
||||||
|
case 0x2e: // L
|
||||||
|
pad_setbtn(&pad, PAD_BTN_START, ispressed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
228
kernel/grid.asm
Normal file
228
kernel/grid.asm
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
; grid - abstraction for grid-like video output
|
||||||
|
;
|
||||||
|
; Collapse OS doesn't support curses-like interfaces: too complicated. However,
|
||||||
|
; in cases where output don't have to go through a serial interface before
|
||||||
|
; being displayed, we have usually have access to a grid-like interface.
|
||||||
|
;
|
||||||
|
; Direct access to this kind of interface allow us to build an abstraction layer
|
||||||
|
; that is very much alike curses but is much simpler underneath. This unit is
|
||||||
|
; this abstraction.
|
||||||
|
;
|
||||||
|
; The principle is simple: we have a cell grid of X columns by Y rows and we
|
||||||
|
; can access those cells by their (X, Y) address. In addition to this, we have
|
||||||
|
; the concept of an active cursor, which will be indicated visually if possible.
|
||||||
|
;
|
||||||
|
; Additionally, this module provides a PutC routine, suitable for plugging into
|
||||||
|
; stdio.
|
||||||
|
;
|
||||||
|
; *** Defines ***
|
||||||
|
;
|
||||||
|
; GRID_COLS: Number of columns in the grid
|
||||||
|
; GRID_ROWS: Number of rows in the grid
|
||||||
|
; GRID_SETCELL: Pointer to routine that sets cell at row D and column E with
|
||||||
|
; character in A. If C is nonzero, this cell must be displayed,
|
||||||
|
; if possible, as the cursor.
|
||||||
|
;
|
||||||
|
; *** Consts ***
|
||||||
|
.equ GRID_SIZE GRID_COLS*GRID_ROWS
|
||||||
|
|
||||||
|
; *** Variables ***
|
||||||
|
; Cursor's column
|
||||||
|
.equ GRID_CURX GRID_RAMSTART
|
||||||
|
; Cursor's row
|
||||||
|
.equ GRID_CURY @+1
|
||||||
|
; Grid's in-memory buffer of the contents on screen. Because we always push to
|
||||||
|
; display right after a change, this is almost always going to be a correct
|
||||||
|
; representation of on-screen display.
|
||||||
|
; The buffer is organized as a rows of columns. The cell at row Y and column X
|
||||||
|
; is at GRID_BUF+(Y*GRID_COLS)+X.
|
||||||
|
.equ GRID_BUF @+1
|
||||||
|
.equ GRID_RAMEND @+GRID_SIZE
|
||||||
|
|
||||||
|
; *** Code ***
|
||||||
|
|
||||||
|
gridInit:
|
||||||
|
xor a
|
||||||
|
ld b, GRID_RAMEND-GRID_RAMEND
|
||||||
|
ld hl, GRID_RAMSTART
|
||||||
|
jp fill
|
||||||
|
|
||||||
|
; Place HL at row D and column E in the buffer
|
||||||
|
; Destroys A
|
||||||
|
_gridPlaceCell:
|
||||||
|
ld hl, GRID_BUF
|
||||||
|
ld a, d
|
||||||
|
or a
|
||||||
|
ret z
|
||||||
|
push de ; --> lvl 1
|
||||||
|
ld de, GRID_COLS
|
||||||
|
.loop:
|
||||||
|
add hl, de
|
||||||
|
dec a
|
||||||
|
jr nz, .loop
|
||||||
|
pop de ; <-- lvl 1
|
||||||
|
; We're at the proper row, now let's advance to cell
|
||||||
|
ld a, e
|
||||||
|
jp addHL
|
||||||
|
|
||||||
|
; Push row D in the buffer onto the screen.
|
||||||
|
gridPushRow:
|
||||||
|
push af
|
||||||
|
push bc
|
||||||
|
push de
|
||||||
|
push hl
|
||||||
|
; Cursor off
|
||||||
|
ld c, 0
|
||||||
|
ld e, c
|
||||||
|
call _gridPlaceCell
|
||||||
|
ld b, GRID_COLS
|
||||||
|
.loop:
|
||||||
|
ld a, (hl)
|
||||||
|
; A, C, D and E have proper values
|
||||||
|
call GRID_SETCELL
|
||||||
|
inc hl
|
||||||
|
inc e
|
||||||
|
djnz .loop
|
||||||
|
|
||||||
|
pop hl
|
||||||
|
pop de
|
||||||
|
pop bc
|
||||||
|
pop af
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Clear row D and push contents to screen
|
||||||
|
gridClrRow:
|
||||||
|
push af
|
||||||
|
push bc
|
||||||
|
push de
|
||||||
|
push hl
|
||||||
|
ld e, 0
|
||||||
|
call _gridPlaceCell
|
||||||
|
xor a
|
||||||
|
ld b, GRID_COLS
|
||||||
|
call fill
|
||||||
|
call gridPushRow
|
||||||
|
|
||||||
|
pop hl
|
||||||
|
pop de
|
||||||
|
pop bc
|
||||||
|
pop af
|
||||||
|
ret
|
||||||
|
|
||||||
|
gridPushScr:
|
||||||
|
push de
|
||||||
|
ld d, GRID_ROWS-1
|
||||||
|
.loop:
|
||||||
|
call gridPushRow
|
||||||
|
dec d
|
||||||
|
jp p, .loop
|
||||||
|
pop de
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Set character under cursor to A
|
||||||
|
gridSetCur:
|
||||||
|
push de
|
||||||
|
push hl
|
||||||
|
push af ; --> lvl 1
|
||||||
|
ld a, (GRID_CURY)
|
||||||
|
ld d, a
|
||||||
|
ld a, (GRID_CURX)
|
||||||
|
ld e, a
|
||||||
|
call _gridPlaceCell
|
||||||
|
pop af \ push af ; <--> lvl 1
|
||||||
|
ld (hl), a
|
||||||
|
call GRID_SETCELL
|
||||||
|
pop af ; <-- lvl 1
|
||||||
|
pop hl
|
||||||
|
pop de
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Clear character under cursor
|
||||||
|
gridClrCur:
|
||||||
|
push af
|
||||||
|
ld a, ' '
|
||||||
|
call gridSetCur
|
||||||
|
pop af
|
||||||
|
ret
|
||||||
|
|
||||||
|
gridLF:
|
||||||
|
call gridClrCur
|
||||||
|
push de
|
||||||
|
push af
|
||||||
|
ld a, (GRID_CURY)
|
||||||
|
call .incA
|
||||||
|
ld d, a
|
||||||
|
call gridClrRow
|
||||||
|
ld (GRID_CURY), a
|
||||||
|
xor a
|
||||||
|
ld (GRID_CURX), a
|
||||||
|
pop af
|
||||||
|
pop de
|
||||||
|
ret
|
||||||
|
.incA:
|
||||||
|
inc a
|
||||||
|
cp GRID_ROWS
|
||||||
|
ret nz ; no rollover
|
||||||
|
; bottom reached, stay on last line and scroll screen
|
||||||
|
push hl
|
||||||
|
push de
|
||||||
|
push bc
|
||||||
|
ld de, GRID_BUF
|
||||||
|
ld hl, GRID_BUF+GRID_COLS
|
||||||
|
ld bc, GRID_SIZE-GRID_COLS
|
||||||
|
ldir
|
||||||
|
pop bc
|
||||||
|
pop de
|
||||||
|
pop hl
|
||||||
|
call gridPushScr
|
||||||
|
dec a
|
||||||
|
ret
|
||||||
|
|
||||||
|
gridBS:
|
||||||
|
call gridClrCur
|
||||||
|
push af
|
||||||
|
ld a, (GRID_CURX)
|
||||||
|
or a
|
||||||
|
jr z, .lineup
|
||||||
|
dec a
|
||||||
|
ld (GRID_CURX), a
|
||||||
|
pop af
|
||||||
|
ret
|
||||||
|
.lineup:
|
||||||
|
; end of line, we need to go up one line. But before we do, are we
|
||||||
|
; already at the top?
|
||||||
|
ld a, (GRID_CURY)
|
||||||
|
or a
|
||||||
|
jr z, .end
|
||||||
|
dec a
|
||||||
|
ld (GRID_CURY), a
|
||||||
|
ld a, GRID_COLS-1
|
||||||
|
ld (GRID_CURX), a
|
||||||
|
.end:
|
||||||
|
pop af
|
||||||
|
ret
|
||||||
|
|
||||||
|
gridPutC:
|
||||||
|
cp LF
|
||||||
|
jr z, gridLF
|
||||||
|
cp BS
|
||||||
|
jr z, gridBS
|
||||||
|
cp ' '
|
||||||
|
ret c ; ignore unhandled control characters
|
||||||
|
|
||||||
|
call gridSetCur
|
||||||
|
push af ; --> lvl 1
|
||||||
|
; Move cursor
|
||||||
|
ld a, (GRID_CURX)
|
||||||
|
cp GRID_COLS-1
|
||||||
|
jr z, .incline
|
||||||
|
; We just need to increase X
|
||||||
|
inc a
|
||||||
|
ld (GRID_CURX), a
|
||||||
|
pop af ; <-- lvl 1
|
||||||
|
ret
|
||||||
|
.incline:
|
||||||
|
; increase line and start anew
|
||||||
|
call gridLF
|
||||||
|
pop af ; <-- lvl 1
|
||||||
|
ret
|
@ -181,8 +181,7 @@ padGetC:
|
|||||||
; no action button pressed, but because our pad status changed, update
|
; no action button pressed, but because our pad status changed, update
|
||||||
; VDP before looping.
|
; VDP before looping.
|
||||||
ld a, (PAD_SELCHR)
|
ld a, (PAD_SELCHR)
|
||||||
call vdpConv
|
call gridSetCur
|
||||||
call vdpSpitC
|
|
||||||
jp padGetC
|
jp padGetC
|
||||||
.return:
|
.return:
|
||||||
ld a, LF
|
ld a, LF
|
||||||
|
@ -17,22 +17,12 @@
|
|||||||
;
|
;
|
||||||
.equ VDP_CTLPORT 0xbf
|
.equ VDP_CTLPORT 0xbf
|
||||||
.equ VDP_DATAPORT 0xbe
|
.equ VDP_DATAPORT 0xbe
|
||||||
|
.equ VDP_COLS 32
|
||||||
; *** Variables ***
|
.equ VDP_ROWS 24
|
||||||
;
|
|
||||||
; Row of cursor
|
|
||||||
.equ VDP_ROW VDP_RAMSTART
|
|
||||||
; Line of cursor
|
|
||||||
.equ VDP_LINE @+1
|
|
||||||
.equ VDP_RAMEND @+1
|
|
||||||
|
|
||||||
; *** Code ***
|
; *** Code ***
|
||||||
|
|
||||||
vdpInit:
|
vdpInit:
|
||||||
xor a
|
|
||||||
ld (VDP_ROW), a
|
|
||||||
ld (VDP_LINE), a
|
|
||||||
|
|
||||||
ld hl, vdpInitData
|
ld hl, vdpInitData
|
||||||
ld b, vdpInitDataEnd-vdpInitData
|
ld b, vdpInitDataEnd-vdpInitData
|
||||||
ld c, VDP_CTLPORT
|
ld c, VDP_CTLPORT
|
||||||
@ -107,19 +97,30 @@ vdpInit:
|
|||||||
out (VDP_CTLPORT), a
|
out (VDP_CTLPORT), a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Spits char set in A at current cursor position. Doesn't move the cursor.
|
; Convert ASCII char in A into a tile index corresponding to that character.
|
||||||
; A is a "sega" char
|
; When a character is unknown, returns 0x5e (a '~' char).
|
||||||
vdpSpitC:
|
vdpConv:
|
||||||
|
; The font is organized to closely match ASCII, so this is rather easy.
|
||||||
|
; We simply subtract 0x20 from incoming A
|
||||||
|
sub 0x20
|
||||||
|
cp 0x5f
|
||||||
|
ret c ; A < 0x5f, good
|
||||||
|
ld a, 0x5e
|
||||||
|
ret
|
||||||
|
|
||||||
|
; grid routine. Sets cell at row D and column E to character A
|
||||||
|
vdpSetCell:
|
||||||
|
call vdpConv
|
||||||
; store A away
|
; store A away
|
||||||
ex af, af'
|
ex af, af'
|
||||||
push bc
|
push bc
|
||||||
ld b, 0 ; we push rotated bits from VDP_LINE into B so
|
ld b, 0 ; we push rotated bits from D into B so
|
||||||
; that we'll already have our low bits from the
|
; that we'll already have our low bits from the
|
||||||
; second byte we'll send right after.
|
; second byte we'll send right after.
|
||||||
; Here, we're fitting a 5-bit line, and a 5-bit column on 16-bit, right
|
; Here, we're fitting a 5-bit line, and a 5-bit column on 16-bit, right
|
||||||
; aligned. On top of that, our righmost bit is taken because our target
|
; aligned. On top of that, our righmost bit is taken because our target
|
||||||
; cell is 2-bytes wide and our final number is a VRAM address.
|
; cell is 2-bytes wide and our final number is a VRAM address.
|
||||||
ld a, (VDP_LINE)
|
ld a, d
|
||||||
sla a ; should always push 0, so no pushing in B
|
sla a ; should always push 0, so no pushing in B
|
||||||
sla a ; same
|
sla a ; same
|
||||||
sla a ; same
|
sla a ; same
|
||||||
@ -127,9 +128,9 @@ vdpSpitC:
|
|||||||
sla a \ rl b
|
sla a \ rl b
|
||||||
sla a \ rl b
|
sla a \ rl b
|
||||||
ld c, a
|
ld c, a
|
||||||
ld a, (VDP_ROW)
|
ld a, e
|
||||||
sla a ; A * 2
|
sla a ; A * 2
|
||||||
or c ; bring in two low bits from VDP_LINE into high
|
or c ; bring in two low bits from D into high
|
||||||
; two bits
|
; two bits
|
||||||
out (VDP_CTLPORT), a
|
out (VDP_CTLPORT), a
|
||||||
ld a, b ; 3 low bits set
|
ld a, b ; 3 low bits set
|
||||||
@ -142,147 +143,6 @@ vdpSpitC:
|
|||||||
out (VDP_DATAPORT), a
|
out (VDP_DATAPORT), a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
vdpPutC:
|
|
||||||
; Then, let's place our cursor. We need to first send our LSB, whose
|
|
||||||
; 6 low bits contain our row*2 (each tile is 2 bytes wide) and high
|
|
||||||
; 2 bits are the two low bits of our line
|
|
||||||
; special case: line feed, carriage return, back space
|
|
||||||
cp LF
|
|
||||||
jr z, vdpLF
|
|
||||||
cp CR
|
|
||||||
jr z, vdpCR
|
|
||||||
cp BS
|
|
||||||
jr z, vdpBS
|
|
||||||
|
|
||||||
push af
|
|
||||||
|
|
||||||
; ... but first, let's convert it.
|
|
||||||
call vdpConv
|
|
||||||
|
|
||||||
; and spit it on screen
|
|
||||||
call vdpSpitC
|
|
||||||
|
|
||||||
; Move cursor. The screen is 32x24
|
|
||||||
ld a, (VDP_ROW)
|
|
||||||
cp 31
|
|
||||||
jr z, .incline
|
|
||||||
; We just need to increase row
|
|
||||||
inc a
|
|
||||||
ld (VDP_ROW), a
|
|
||||||
|
|
||||||
pop af
|
|
||||||
ret
|
|
||||||
.incline:
|
|
||||||
; increase line and start anew
|
|
||||||
call vdpCR
|
|
||||||
call vdpLF
|
|
||||||
pop af
|
|
||||||
ret
|
|
||||||
|
|
||||||
vdpCR:
|
|
||||||
call vdpClrPos
|
|
||||||
push af
|
|
||||||
xor a
|
|
||||||
ld (VDP_ROW), a
|
|
||||||
pop af
|
|
||||||
ret
|
|
||||||
|
|
||||||
vdpLF:
|
|
||||||
; we don't call vdpClrPos on LF because we expect it to be preceded by
|
|
||||||
; a CR, which already cleared the pos. If we cleared it now, we would
|
|
||||||
; clear the first char of the line.
|
|
||||||
push af
|
|
||||||
ld a, (VDP_LINE)
|
|
||||||
call .incA
|
|
||||||
call vdpClrLine
|
|
||||||
; Also clear the line after this one
|
|
||||||
push af ; --> lvl 1
|
|
||||||
call .incA
|
|
||||||
call vdpClrLine
|
|
||||||
pop af ; <-- lvl 1
|
|
||||||
ld (VDP_LINE), a
|
|
||||||
pop af
|
|
||||||
ret
|
|
||||||
.incA:
|
|
||||||
inc a
|
|
||||||
cp 24
|
|
||||||
ret nz ; no rollover
|
|
||||||
; bottom reached, roll over to top of screen
|
|
||||||
xor a
|
|
||||||
ret
|
|
||||||
|
|
||||||
vdpBS:
|
|
||||||
call vdpClrPos
|
|
||||||
push af
|
|
||||||
ld a, (VDP_ROW)
|
|
||||||
or a
|
|
||||||
jr z, .lineup
|
|
||||||
dec a
|
|
||||||
ld (VDP_ROW), a
|
|
||||||
pop af
|
|
||||||
ret
|
|
||||||
.lineup:
|
|
||||||
; end of line
|
|
||||||
ld a, 31
|
|
||||||
ld (VDP_ROW), a
|
|
||||||
; we have to go one line up
|
|
||||||
ld a, (VDP_LINE)
|
|
||||||
or a
|
|
||||||
jr z, .nowrap
|
|
||||||
; We have to wrap to the bottom of the screen
|
|
||||||
ld a, 24
|
|
||||||
.nowrap:
|
|
||||||
dec a
|
|
||||||
ld (VDP_LINE), a
|
|
||||||
pop af
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Clear tile under cursor
|
|
||||||
vdpClrPos:
|
|
||||||
push af
|
|
||||||
xor a ; space
|
|
||||||
call vdpSpitC
|
|
||||||
pop af
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Clear line number A
|
|
||||||
vdpClrLine:
|
|
||||||
; see comments in vdpSpitC for VRAM details.
|
|
||||||
push af
|
|
||||||
; first, get the two LSB at MSB pos.
|
|
||||||
rrca \ rrca
|
|
||||||
push af ; --> lvl 1
|
|
||||||
and 0b11000000
|
|
||||||
; That's our first address byte
|
|
||||||
out (VDP_CTLPORT), a
|
|
||||||
pop af ; <-- lvl 1
|
|
||||||
; Then, get those 3 other bits at LSB pos. Our popped A has already
|
|
||||||
; done 2 RRCA, which means that everything is in place.
|
|
||||||
and 0b00000111
|
|
||||||
or 0x78
|
|
||||||
out (VDP_CTLPORT), a
|
|
||||||
; We're at the right place. Let's just spit 32*2 null bytes
|
|
||||||
xor a
|
|
||||||
push bc ; --> lvl 1
|
|
||||||
ld b, 64
|
|
||||||
.loop:
|
|
||||||
out (VDP_DATAPORT), a
|
|
||||||
djnz .loop
|
|
||||||
pop bc ; <-- lvl 1
|
|
||||||
pop af
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Convert ASCII char in A into a tile index corresponding to that character.
|
|
||||||
; When a character is unknown, returns 0x5e (a '~' char).
|
|
||||||
vdpConv:
|
|
||||||
; The font is organized to closely match ASCII, so this is rather easy.
|
|
||||||
; We simply subtract 0x20 from incoming A
|
|
||||||
sub 0x20
|
|
||||||
cp 0x5f
|
|
||||||
ret c ; A < 0x5f, good
|
|
||||||
ld a, 0x5e
|
|
||||||
ret
|
|
||||||
|
|
||||||
; VDP initialisation data
|
; VDP initialisation data
|
||||||
vdpInitData:
|
vdpInitData:
|
||||||
; 0x8x == set register X
|
; 0x8x == set register X
|
||||||
|
@ -16,12 +16,16 @@
|
|||||||
.equ PAD_RAMSTART RAMSTART
|
.equ PAD_RAMSTART RAMSTART
|
||||||
.inc "sms/pad.asm"
|
.inc "sms/pad.asm"
|
||||||
|
|
||||||
.equ VDP_RAMSTART PAD_RAMEND
|
|
||||||
.inc "sms/vdp.asm"
|
.inc "sms/vdp.asm"
|
||||||
|
.equ GRID_RAMSTART PAD_RAMEND
|
||||||
|
.equ GRID_COLS VDP_COLS
|
||||||
|
.equ GRID_ROWS VDP_ROWS
|
||||||
|
.equ GRID_SETCELL vdpSetCell
|
||||||
|
.inc "grid.asm"
|
||||||
|
|
||||||
.equ STDIO_RAMSTART VDP_RAMEND
|
.equ STDIO_RAMSTART GRID_RAMEND
|
||||||
.equ STDIO_GETC padGetC
|
.equ STDIO_GETC padGetC
|
||||||
.equ STDIO_PUTC vdpPutC
|
.equ STDIO_PUTC gridPutC
|
||||||
.inc "stdio.asm"
|
.inc "stdio.asm"
|
||||||
|
|
||||||
; *** BASIC ***
|
; *** BASIC ***
|
||||||
@ -51,6 +55,7 @@ init:
|
|||||||
|
|
||||||
ld sp, RAMEND
|
ld sp, RAMEND
|
||||||
|
|
||||||
|
call gridInit
|
||||||
call padInit
|
call padInit
|
||||||
call vdpInit
|
call vdpInit
|
||||||
call basInit
|
call basInit
|
||||||
|
@ -18,12 +18,16 @@
|
|||||||
.equ KBD_FETCHKC smskbdFetchKCB
|
.equ KBD_FETCHKC smskbdFetchKCB
|
||||||
.inc "kbd.asm"
|
.inc "kbd.asm"
|
||||||
|
|
||||||
.equ VDP_RAMSTART KBD_RAMEND
|
|
||||||
.inc "sms/vdp.asm"
|
.inc "sms/vdp.asm"
|
||||||
|
.equ GRID_RAMSTART KBD_RAMEND
|
||||||
|
.equ GRID_COLS VDP_COLS
|
||||||
|
.equ GRID_ROWS VDP_ROWS
|
||||||
|
.equ GRID_SETCELL vdpSetCell
|
||||||
|
.inc "grid.asm"
|
||||||
|
|
||||||
.equ STDIO_RAMSTART VDP_RAMEND
|
.equ STDIO_RAMSTART GRID_RAMEND
|
||||||
.equ STDIO_GETC kbdGetC
|
.equ STDIO_GETC kbdGetC
|
||||||
.equ STDIO_PUTC vdpPutC
|
.equ STDIO_PUTC gridPutC
|
||||||
.inc "stdio.asm"
|
.inc "stdio.asm"
|
||||||
|
|
||||||
; *** BASIC ***
|
; *** BASIC ***
|
||||||
@ -64,6 +68,7 @@ init:
|
|||||||
out (0x3f), a
|
out (0x3f), a
|
||||||
|
|
||||||
call kbdInit
|
call kbdInit
|
||||||
|
call gridInit
|
||||||
call vdpInit
|
call vdpInit
|
||||||
call basInit
|
call basInit
|
||||||
jp basStart
|
jp basStart
|
||||||
|
@ -47,12 +47,16 @@
|
|||||||
.equ KBD_FETCHKC smskbdFetchKCB
|
.equ KBD_FETCHKC smskbdFetchKCB
|
||||||
.inc "kbd.asm"
|
.inc "kbd.asm"
|
||||||
|
|
||||||
.equ VDP_RAMSTART KBD_RAMEND
|
|
||||||
.inc "sms/vdp.asm"
|
.inc "sms/vdp.asm"
|
||||||
|
.equ GRID_RAMSTART KBD_RAMEND
|
||||||
|
.equ GRID_COLS VDP_COLS
|
||||||
|
.equ GRID_ROWS VDP_ROWS
|
||||||
|
.equ GRID_SETCELL vdpSetCell
|
||||||
|
.inc "grid.asm"
|
||||||
|
|
||||||
.equ STDIO_RAMSTART VDP_RAMEND
|
.equ STDIO_RAMSTART GRID_RAMEND
|
||||||
.equ STDIO_GETC kbdGetC
|
.equ STDIO_GETC kbdGetC
|
||||||
.equ STDIO_PUTC vdpPutC
|
.equ STDIO_PUTC gridPutC
|
||||||
.inc "stdio.asm"
|
.inc "stdio.asm"
|
||||||
|
|
||||||
.equ MMAP_START 0xd700
|
.equ MMAP_START 0xd700
|
||||||
@ -124,6 +128,7 @@ init:
|
|||||||
call fsOn
|
call fsOn
|
||||||
|
|
||||||
call kbdInit
|
call kbdInit
|
||||||
|
call gridInit
|
||||||
call vdpInit
|
call vdpInit
|
||||||
|
|
||||||
call basInit
|
call basInit
|
||||||
@ -165,7 +170,7 @@ f1PutB:
|
|||||||
ld ix, FS_HANDLES+FS_HANDLE_SIZE
|
ld ix, FS_HANDLES+FS_HANDLE_SIZE
|
||||||
jp fsPutB
|
jp fsPutB
|
||||||
|
|
||||||
; last time I checked, PC at this point was 0x1e92. Let's give us a nice margin
|
; last time I checked, PC at this point was 0x128f. Let's give us a nice margin
|
||||||
; for the start of ed.
|
; for the start of ed.
|
||||||
.fill 0x1f00-$
|
.fill 0x1f00-$
|
||||||
.bin "ed.bin"
|
.bin "ed.bin"
|
||||||
|
Loading…
Reference in New Issue
Block a user